/* Ticker, services, pricing, contact and footer. */

.ticker { background: var(--surface); border-block: 1px solid var(--line); overflow: hidden; padding: 16px 0; white-space: nowrap; }
.ticker__run { display: inline-block; color: var(--soft); font-size: 15px; font-weight: 500; animation: tick 90s linear infinite; }
.ticker__run.is-driven { animation: none; }
@keyframes tick { to { transform: translateX(-50%); } }

.sec { padding-block: clamp(64px, 8vw, 112px); }
.sec__title { margin: 0 0 clamp(28px, 4vw, 52px); font-weight: var(--display-weight); letter-spacing: var(--display-track); font-size: clamp(52px, 8vw, 128px); line-height: .95; }

/* Services. Without motion: equal boxes, headings aligned at the top. */
.folds { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
@media (max-width: 1100px) { .folds { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .folds { grid-template-columns: 1fr; } }
.fold { padding: clamp(20px, 3vw, 32px); }
.fold__label { display: none; }
/* Each service's clip (clips.js). Without the folds' motion it's a picture at the top of each box. */
.fold__media { display: block; position: relative; aspect-ratio: 16 / 9; margin: 0 0 16px; overflow: hidden; border-radius: 8px; background: #0b0a09; }
.fold__title { margin: 0 0 10px; font-weight: var(--display-weight); letter-spacing: -.03em; font-size: 28px; line-height: 1.05; }
.fold__text { margin: 0; color: var(--soft); }
.fold__link { display: inline-block; margin-top: 2px; padding: 12px 0; color: var(--accent); font-weight: 600; font-size: 14px; } /* 12px above and below: a 44px tap area */

/* With motion (folds.js): the stage is pinned and the services open one at a time as the page scrolls. The open
   fold widens (flex-grow) while the rest narrow to strips with their names running up the side. */
.folds-sec.is-moving { padding-block: 0; }
.folds-sec.is-moving .folds__stage { position: sticky; top: 0; height: 100vh; height: 100svh; display: flex; flex-direction: column; justify-content: center; padding: 76px 0 28px; }
.folds-sec.is-moving .sec__title { font-size: clamp(44px, min(7vw, 11vh), 128px); margin-bottom: clamp(18px, 3.5vh, 40px); }
.folds-sec.is-moving .folds { display: flex; gap: 10px; height: clamp(320px, 56vh, 560px); }
.folds-sec.is-moving .fold { flex: 0 0 76px; position: relative; isolation: isolate; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start; padding: clamp(22px, 2.6vw, 36px); transition: flex-grow .7s cubic-bezier(.25, 1, .5, 1), border-color .3s; }
.folds-sec.is-moving .fold.is-open { flex-grow: 1; }
.folds-sec.is-moving .fold:not(.is-open):hover { border-color: var(--accent); }
.folds-sec.is-moving .fold:has(.fold__tab:focus-visible) { outline: 2px solid var(--accent); outline-offset: 3px; }
.folds-sec.is-moving .fold::before { content: ''; position: absolute; inset: 0; z-index: -1; opacity: 0; transition: opacity .6s; background: radial-gradient(90% 80% at 88% 8%, var(--accent), transparent 62%), radial-gradient(70% 70% at 20% 110%, var(--ember-line), transparent 70%); }
.folds-sec.is-moving .fold.is-open::before { opacity: .2; }
/* The strip labels are decoration only (pointer-events: none), so taps reach the tab or the open panel's link */
.folds-sec.is-moving .fold__label { display: flex; position: absolute; inset: 0; pointer-events: none; flex-direction: column; align-items: center; justify-content: space-between; padding: 22px 0; transition: opacity .3s; }
.folds-sec.is-moving .fold__num { color: var(--accent); font-weight: 600; font-size: 15px; }
.folds-sec.is-moving .fold__name { writing-mode: vertical-rl; transform: rotate(180deg); white-space: nowrap; font-weight: var(--display-weight); letter-spacing: -.02em; font-size: 22px; }
.folds-sec.is-moving .fold.is-open .fold__label { opacity: 0; }
.folds-sec.is-moving .fold__title, .folds-sec.is-moving .fold__body { width: min(560px, 62vw); opacity: 0; transition: opacity .25s; }
.folds-sec.is-moving .fold.is-open .fold__title, .folds-sec.is-moving .fold.is-open .fold__body { opacity: 1; transition: opacity .5s .25s; }
.folds-sec.is-moving .fold__title { font-size: clamp(34px, 3.6vw, 56px); margin-bottom: 14px; }
.fold__tab { all: unset; cursor: pointer; }
.folds-sec.is-moving .fold:not(.is-open) .fold__tab::after { content: ''; position: absolute; inset: 0; }
.folds-sec.is-moving .fold__text { font-size: 18px; max-width: 40ch; }
.folds-sec.is-moving .fold__media { position: absolute; top: 0; right: 0; z-index: -1; width: 70%; height: 80%; margin: 0; aspect-ratio: auto; border-radius: 0; background: none;
  -webkit-mask-image: radial-gradient(ellipse 60% 62% at 60% 42%, #000 45%, transparent 100%); mask-image: radial-gradient(ellipse 60% 62% at 60% 42%, #000 45%, transparent 100%); }
/* Phones: the folds stack and open downwards, and the clip fills the top of the open panel, fading out above the
   heading; each strip still shows its number. */
@media (max-width: 760px) {
  .folds-sec.is-moving .folds__stage { padding: 80px 0 20px; }
  .folds-sec.is-moving .folds__stage > .wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  .folds-sec.is-moving .sec__title { font-size: clamp(34px, 10.5vw, 48px); margin-bottom: 16px; }
  .folds-sec.is-moving .folds { flex: 1; min-height: 0; max-height: 600px; flex-direction: column; gap: 8px; height: auto; }
  .folds-sec.is-moving .fold { flex-basis: 52px; padding: 18px; }
  .folds-sec.is-moving .fold__label { bottom: auto; height: 52px; flex-direction: row; justify-content: flex-start; gap: 14px; padding: 0 18px; }
  .folds-sec.is-moving .fold__name { writing-mode: horizontal-tb; transform: none; font-size: 19px; }
  .folds-sec.is-moving .fold__title, .folds-sec.is-moving .fold__body { width: 100%; }
  .folds-sec.is-moving .fold__title { font-size: 28px; margin-bottom: 10px; }
  .folds-sec.is-moving .fold__text { font-size: 16px; line-height: 1.5; }
  .folds-sec.is-moving .fold__media { width: 100%; height: 100%; -webkit-mask-image: linear-gradient(#000 25%, transparent 75%); mask-image: linear-gradient(#000 25%, transparent 75%); }
}
@media (prefers-reduced-motion: reduce) { .fold, .fold::before, .fold__title, .fold__body, .fold__label { transition: none !important; } }

/* Clips (clips.js): each fills its box. In a fade loop, the copy on top (loop.js) fades in and out over the 2s its
   FADE waits for. */
.clip { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }
.clip + .clip { opacity: 0; transition: opacity 2s linear; }
.clip + .clip.is-on { opacity: 1; }

/* Pricing */
.pricing__lede { margin: 0 0 28px; color: var(--soft); font-size: 18px; max-width: 60ch; }
.plans { border-top: 1px solid var(--line); }
.plan { display: grid; grid-template-columns: minmax(0, 1fr) 260px 120px; gap: 24px; align-items: center; padding: 22px 0; border-bottom: 1px solid var(--line); }
.plan__name { margin: 0; font-weight: var(--display-weight); letter-spacing: -.025em; font-size: 26px; line-height: 1.1; }
.plan__desc { margin: 6px 0 0; color: var(--soft); max-width: 58ch; }
.plan__price { text-align: right; }
.plan__amt { display: block; font-weight: var(--display-weight); letter-spacing: -.03em; font-size: 30px; line-height: 1.1; }
.plan__std { display: block; margin-top: 2px; font-size: 14px; color: var(--muted); }

/* With motion (fan-gsap.js), the plans fan out like a hand of cards. The cards are placed by GSAP from the middle
   of the row; the one in front (pointed at, tapped or tabbed to) is upright and full size. */
#pricing { overflow-x: clip; }
.fan__hint { display: none; }
.plans.is-fanned { --card-w: min(340px, 80vw); position: relative; border-top: 0; touch-action: pan-y; }
.plans.is-fanned .plan { position: absolute; top: 40px; left: 50%; width: var(--card-w); margin-left: calc(var(--card-w) / -2); display: flex; flex-direction: column; align-items: stretch; gap: 0; padding: clamp(22px, 2.4vw, 28px); border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: 0 24px 60px rgba(0, 0, 0, .45); will-change: transform; transition: border-color .3s; }
.plans.is-fanned .plan.is-front { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); }
.plans.is-fanned .plan__main { flex: 1; }
.plans.is-fanned .plan__name { font-size: clamp(24px, 2.2vw, 30px); }
.plans.is-fanned .plan__price { text-align: inherit; margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line); }
.plans.is-fanned .plan__amt { font-size: clamp(30px, 2.8vw, 40px); }
.plans.is-fanned .plan .btn { margin-top: 18px; align-self: flex-start; }
.plans.is-fanned .plan--right { text-align: right; }
.plans.is-fanned .plan--right .plan__desc { margin-left: auto; }
.plans.is-fanned .plan--right .btn { align-self: flex-end; }
/* Phones and portrait tablets: a swipe row instead of the fan (fan-gsap.js picks one by width, at 900px). Cards snap to the middle, the
   next one peeks in, and the dots below show where you are. */
.plans.is-swipe { position: relative; display: flex; align-items: stretch; gap: 0; perspective: 900px; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); padding: 6px var(--gutter) 14px; margin-inline: calc(-1 * var(--gutter)); border-top: 0; scrollbar-width: none; overscroll-behavior-x: contain; }
.plans.is-swipe::-webkit-scrollbar { display: none; }
.plans.is-swipe .plan { position: relative; flex: 0 0 72%; scroll-snap-align: center; display: flex; flex-direction: column; align-items: stretch; gap: 0; padding: 22px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); will-change: transform; }
/* The cards either side of the middle dim as they turn away (fan-gsap.js sets --dim) */
.plans.is-swipe .plan::after { content: ''; position: absolute; inset: -1px; border-radius: inherit; background: #000; opacity: var(--dim, 0); pointer-events: none; }
.plans.is-swipe .plan__main { flex: 1; }
.plans.is-swipe .plan__name { font-size: 26px; }
.plans.is-swipe .plan__price { text-align: left; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); }
.plans.is-swipe .plan__amt { font-size: 32px; }
.plans.is-swipe .plan .btn { margin-top: 18px; align-self: flex-start; }
@media (min-width: 641px) { .plans.is-swipe .plan { flex-basis: 44%; } } /* tablets: more of the cards either side in view */
.plans-dots { display: flex; justify-content: center; gap: 0; margin-top: 0; }
.plans-dot { display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; background: none; cursor: pointer; }
.plans-dot::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--line); transition: background .3s, transform .3s; }
.plans-dot[aria-current="true"]::before { background: var(--accent); transform: scale(1.3); }
.plans.is-draggable { cursor: grab; }
.plans.is-draggable:active { cursor: grabbing; }
.plans.is-fanned + .fan__hint { display: block; margin: 8px 0 0; text-align: center; color: var(--muted); }
.fan__hint-touch { display: none; }
@media (hover: none) { .fan__hint-mouse { display: none; } .fan__hint-touch { display: inline; } }
.plan .btn { justify-self: end; }
.plans--small .plan { padding: 16px 0; }
.plans--small .plan__name { font-size: 19px; }
.plans--small .plan__amt { font-size: 21px; }
.addons__title { margin: 48px 0 16px; font-weight: var(--display-weight); letter-spacing: -.02em; font-size: 22px; }
.fine { margin: 18px 0 0; color: var(--muted); font-size: 14px; }

/* FAQs: native accordions in rows, like the pricing list */
.faqs { border-top: 1px solid var(--line); max-width: 900px; }
.faq { border-bottom: 1px solid var(--line); }
.faq__q { display: flex; justify-content: space-between; align-items: center; gap: 24px; padding: 22px 0; cursor: pointer; list-style: none; font-weight: var(--display-weight); letter-spacing: -.02em; font-size: clamp(19px, 2vw, 24px); line-height: 1.2; }
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after { content: '+'; flex: none; font-weight: 500; font-size: 1.2em; line-height: 1; color: var(--muted); transition: transform .3s var(--spring); }
.faq[open] .faq__q::after { transform: rotate(45deg); }
.faq__a { margin: 0; padding: 0 0 22px; color: var(--soft); max-width: 64ch; line-height: 1.6; overflow: hidden; }
@media (prefers-reduced-motion: reduce) { .faq__q::after { transition: none; } }
@media (max-width: 760px) {
  .plan { grid-template-columns: 1fr; gap: 10px; }
  .plan__price { text-align: left; }
  .plan .btn { justify-self: start; }
}

/* Contact */
.contact { display: grid; grid-template-columns: 1fr 1.3fr; gap: clamp(32px, 6vw, 96px); align-items: start; }
@media (max-width: 860px) { .contact { grid-template-columns: 1fr; } }
#contact .sec__title { font-size: clamp(44px, 5.4vw, 84px); margin-bottom: 24px; }
.contact__lede { color: var(--soft); max-width: 34ch; font-size: 18px; margin: 0; }
.contact__mail a { color: var(--accent); font-weight: 600; }
/* The studio's gem turning slowly beside the form, its edges fading into the page */
.contact__gem { position: relative; width: min(340px, 100%); aspect-ratio: 1; margin-top: clamp(24px, 5vh, 56px);
  -webkit-mask-image: radial-gradient(closest-side, #000 60%, transparent); mask-image: radial-gradient(closest-side, #000 60%, transparent); }
@media (max-width: 860px) { .contact__gem { display: none; } } /* phones: straight on to the form */
.form { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; padding: clamp(20px, 3vw, 32px); }
.form .field--wide, .form__foot { grid-column: 1 / -1; }
@media (max-width: 560px) { .form { grid-template-columns: 1fr; } }
.field { display: grid; gap: 6px; }
.field label { font-size: 13px; font-weight: 600; color: var(--soft); }
.field__opt { font-weight: 500; color: var(--muted); }
.field input, .field select, .field textarea { font: inherit; color: inherit; width: 100%; min-height: 48px; padding: 12px 14px; background: var(--field-bg); border: 1px solid var(--line); border-radius: 6px; transition: border-color .2s, box-shadow .2s; }
.field textarea { min-height: 140px; resize: vertical; }
.field select option { background: var(--bg); }
.field input:focus, .field select:focus, .field textarea:focus { outline: 2px solid transparent; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
.field__err { display: none; font-size: 13px; color: var(--danger); }
.field--error .field__err { display: block; }
.field--error input, .field--error textarea { border-color: var(--danger); }
.form__foot { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.form__status { margin: 0; font-size: 14px; }
/* The spam trap: a field people never see (bots fill in everything). */
.hp { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.form__status[data-state="error"] { color: var(--danger); }
.form__status a { color: var(--accent); font-weight: 600; }
.form__note { flex-basis: 100%; margin: 0; font-size: 14px; color: var(--muted); }
.form__note a, .foot__in a { position: relative; color: inherit; }
.form__note a::before, .foot__in a::before { content: ''; position: absolute; inset: -12px -4px; } /* a 44px tap area around a small link */

/* Footer */
.foot { padding-block: 24px 40px; color: var(--muted); }
.foot__mark { margin: 0; font-weight: var(--display-weight); letter-spacing: -.06em; white-space: nowrap; text-align: center; font-size: min(14vw, 200px); line-height: .85; overflow: hidden;
  background: linear-gradient(180deg, var(--fg) 0%, transparent 95%); -webkit-background-clip: text; background-clip: text; color: transparent; opacity: .9; }
/* Light moving inside the name (clips.js): the clip shows through white letters on black (multiply), and that
   is screened onto the page, so the black drops away and only the lit letters show. The plain name dims under it. */
.foot__brand { position: relative; }
.foot__brand > .foot__mark { transition: opacity 2s linear; }
.foot__light { position: absolute; inset: 0; isolation: isolate; mix-blend-mode: screen; pointer-events: none; opacity: 0; transition: opacity 2s linear; }
.foot__knock { position: absolute; inset: 0; background: #000; -webkit-background-clip: border-box; background-clip: border-box; color: #fff; opacity: 1; mix-blend-mode: multiply; }
.foot__knock span { background: linear-gradient(180deg, #fff 10%, #000 95%); -webkit-background-clip: text; background-clip: text; color: transparent; }
.foot__brand:has(.clip.is-on) .foot__light { opacity: 1; }
.foot__brand:has(.clip.is-on) > .foot__mark { opacity: .3; }
.is-lite .foot__light { display: none; } /* lite mode: the plain name */
.is-lite .foot__brand > .foot__mark { opacity: .9; }
.foot__in { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; border-top: 1px solid var(--line); padding-top: 20px; margin-top: 20px; }

@media (prefers-reduced-motion: reduce) { .ticker__run { animation: none; } }

/* 404 page */
.notfound { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 20px; }
.notfound .sec__title { margin: 0; }
.notfound__logo img { display: block; width: auto; height: 56px; }
.notfound__text { margin: 0; color: var(--soft); font-size: 18px; max-width: 40ch; }

/* Privacy policy page */
.legal { padding-block: 120px 64px; max-width: 72ch; }
.legal .sec__title { font-size: clamp(44px, 6vw, 88px); margin-bottom: 12px; }
.legal__meta { margin: 0 0 32px; color: var(--muted); font-size: 14px; }
.legal h2 { margin: 40px 0 10px; font-weight: var(--display-weight); letter-spacing: -.025em; font-size: 26px; line-height: 1.15; }
.legal h3 { margin: 24px 0 6px; font-size: 17px; font-weight: 700; }
.legal p, .legal li { color: var(--soft); line-height: 1.65; }
.legal p { margin: 0 0 12px; }
.legal ul { margin: 0 0 12px; padding-left: 1.2em; }
.legal li { margin-bottom: 6px; }
.legal strong { color: var(--fg); }
.legal a:not(.btn) { color: var(--fg); text-decoration-color: var(--accent); text-underline-offset: .15em; }
.legal__back { margin-top: 40px; }


/* Opener: the headline is a window onto a moving clip. The knock-out layer is the page colour with pure white
   letters; multiply lets the clip show only through the letters. Until a clip is set, a warm glow drifts instead. */
.opener { position: relative; height: 100vh; height: 100svh; overflow: hidden; isolation: isolate; }
.opener__clip { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 2s linear; }
.opener__clip.is-on { opacity: 1; } /* two copies crossfade to loop (loop.js); the 2s matches its FADE */
.opener__glow { position: absolute; inset: -25%; background: radial-gradient(closest-side at 30% 40%, var(--ember-glow), transparent 70%), radial-gradient(closest-side at 72% 62%, var(--accent), transparent 70%), radial-gradient(closest-side at 50% 50%, var(--ember-line), transparent) var(--bg); animation: opener-drift 16s ease-in-out infinite alternate; }
/* A hint of ember warmth on the smoke: soft ember light from the lower left, the brightest wisps staying ivory. */
.opener__warmth { position: absolute; inset: 0; pointer-events: none; background: radial-gradient(70% 90% at 22% 72%, var(--ember-glow), transparent 70%), radial-gradient(60% 70% at 82% 18%, var(--ember-line), transparent 75%); mix-blend-mode: soft-light; opacity: 0; transition: opacity 2s linear; }
.opener.has-clip .opener__warmth { opacity: .65; }
.opener__glow { transition: opacity 2s linear; }
.opener.has-clip .opener__glow { opacity: 0; } /* the glow fades out as the clip fades in */
@keyframes opener-drift { to { transform: translate(6%, -5%) rotate(10deg) scale(1.12); } }
.opener__knock { position: absolute; inset: 0; display: flex; align-items: center; padding: 64px var(--gutter) 0; background: var(--bg); color: #fff; mix-blend-mode: multiply; }
.opener .hero-type { margin: 0; display: block; font-size: clamp(56px, 10vw, 190px); line-height: .9; max-width: 12ch; }
.opener .hero-type > span { display: inline; } /* plain inline, so SplitText (headline.js) finds every line break */
.opener .mark { color: #fff; background-image: linear-gradient(#fff, #fff); }
.opener .mark__glow { background: none; -webkit-text-fill-color: currentColor; animation: none; }
.opener__hint { position: absolute; left: var(--gutter); bottom: 28px; margin: 0; color: var(--muted); }
.opener__hint-scroll { display: block; margin-top: 8px; color: var(--soft); font-size: 15px; font-weight: 500; letter-spacing: 0; text-transform: none; } /* its own line, in plain words */
@media (max-width: 760px) { .opener .hero-type { font-size: 15vw; } }
/* headline.js splits the headline into lines that rise from behind their own edges. Until then it's hidden; if
   the script never runs, it shows anyway after a moment. */
.opener .hero-type { opacity: 0; animation: show-anyway 0s 1.2s forwards; }
.opener .hero-type.is-split { opacity: 1; animation: none; }
/* The tight line height puts the underline just below each line, so each line's mask reaches a little lower. */
.opener .hl-line-mask { padding-bottom: .14em; margin-bottom: -.14em; }
@keyframes show-anyway { to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .opener .hero-type { opacity: 1; animation: none; } }
@media (prefers-reduced-motion: reduce) { .opener__glow { animation: none; } }

