// FAQ — "The Index" v2
// Real questions scraped from mtsurfaceprotectors.com/faq, in original order.
// Layout: sticky chapter rail + searchable index column on the left,
// a "stage" reading panel on the right that holds the active answer.
// On mobile the panel collapses inline like a classic accordion.

const { useState: useFS, useEffect: useFE, useRef: useFR, useMemo: useFM, useLayoutEffect: useFL } = React;

const FT = window.__TWEAKS__ || {};

// ============================================================
// CHAPTER PALETTE — every chapter gets its own personality
// All accents share warm, refined tones that live in the existing palette
// ============================================================
const CHAPTER_THEME = {
  "What It Is":       { accent: "#6B1416", tint: "#F4E8E5", deep: "#4A0E10", label: "Maroon"     },
  "Looks & Finish":   { accent: "#8B5A2B", tint: "#F2E8D8", deep: "#5C3C1D", label: "Bronze"     },
  "How It Performs":  { accent: "#3B5A4A", tint: "#E2EBE3", deep: "#283D33", label: "Forest"     },
  "Living With It":   { accent: "#3F4F6B", tint: "#DFE6EE", deep: "#2A3548", label: "Indigo"     },
  "The Install":      { accent: "#9B4A2E", tint: "#F0E0D6", deep: "#6B331F", label: "Terracotta" },
  "Our Promise":      { accent: "#5A3550", tint: "#EBE0E7", deep: "#3D2436", label: "Plum"       },
};
const themeFor = (cat) => CHAPTER_THEME[cat] || CHAPTER_THEME["What It Is"];

// ============================================================
// DATA — every question from the live FAQ page, exact wording for titles.
// Answers are sourced from the M&T blog "Everything You Need to Know
// About StoneGuard" + StoneGuard certified-installer materials, written
// in M&T's voice. Chapters added by us so the rail has structure.
// ============================================================
const FAQ_DATA = [
  {
    cat: "What It Is",
    blurb: "What StoneGuard actually is, and where we work.",
    items: [
      {
        q: "What areas do you cover?",
        a: "We're based in the tri-state and serve homes across New York, New Jersey, and Pennsylvania. Most installs are within a comfortable drive of NYC, but we travel further regularly — get in touch with your address and we'll confirm scheduling and travel for your project.",
        tldr: "NY · NJ · PA. Travel further on request."
      },
      {
        q: "What is StoneGuard® & how is it different from sealers?",
        a: "StoneGuard® is a patented, multi-layer protective film engineered specifically for natural stone — about 5 mils thick, with a nano-coated top layer that takes the brunt of everyday wear. Sealers are a different category entirely: they're liquid chemicals that soak into the pores of the stone, require periodic reapplication, and offer limited protection against acidic spills. StoneGuard is a physical barrier that lives on top of the stone, blocks etching and stains in real time, and can simply be replaced when it ages.",
        tldr: "A physical film, not a liquid sealer. Stops etching."
      },
      {
        q: "Why choose StoneGuard instead of other films?",
        a: "StoneGuard was engineered from every layer specifically for stone — including a gas-permeable adhesive that lets the slab breathe. Most \"competing\" countertop films are repurposed automotive paint protection film or window tint, originally designed for glass and metal, not calcite. Repurposed films can seal the pores of the stone or behave unpredictably over time. StoneGuard's technology and its application to stone are protected by patent, and we're trained and certified to install it.",
        tldr: "Built for stone from the ground up. Patented."
      },
      {
        q: "Who is M&T Surface Protectors?",
        a: "We're a family-run, certified StoneGuard installation company based in the tri-state. Michael and the team have spent years specializing in one thing — protecting and restoring high-end natural stone in private residences. We don't do flooring, we don't do tile contracting on the side. Stone surfaces are the entire business, which is why our work and our pace look different from a general contractor.",
        tldr: "Family-run, certified, focused only on stone surfaces."
      },
      {
        q: "What stones does StoneGuard work on?",
        a: "Marble, quartzite, granite, soapstone, limestone, travertine, onyx, and engineered quartz — essentially any natural or man-made stone slab with a relatively smooth surface. Highly textured leathered or rough-hewn finishes can be a challenge for adhesion; we'll evaluate your specific slab during the consultation and tell you honestly whether StoneGuard is the right call.",
        tldr: "Most stones — marble, quartzite, granite, quartz, soapstone, more."
      },
      {
        q: "Where can StoneGuard be installed in my home?",
        a: "Anywhere there's a flat stone surface that takes daily use: kitchen counters and islands, bathroom vanities, bar tops, dining tables, fireplace surrounds, conference tables, and waterfall edges. We've also done coffee tables and built-in desks. If it's stone and you use it, it's a candidate.",
        tldr: "Counters, islands, vanities, bars, tables, fireplaces."
      },
      {
        q: "Can StoneGuard be used outdoors?",
        a: "No — StoneGuard was developed and tested for indoor use only. Outdoor exposure introduces temperature swings, moisture cycles, and UV intensity that the film isn't engineered for. If you have an outdoor kitchen or patio bar that needs protection, give us a call and we'll point you toward the right product for that environment.",
        tldr: "Indoor only. Outdoor stone needs a different product."
      },
    ]
  },
  {
    cat: "Looks & Finish",
    blurb: "How it'll look on your stone — polished, honed, or otherwise.",
    items: [
      {
        q: "Do I need to get my stone restored before StoneGuard is applied?",
        a: "If your stone already has etching, staining, or surface damage, yes — the film bonds to whatever's underneath, so we want to start from a clean canvas. We handle the restoration ourselves: honing, polishing, stain removal, and prep all happen on the same project. If your stone is in good shape, we go straight to install. We'll tell you honestly which camp you're in during the consultation.",
        tldr: "Yes if the stone is damaged. We restore it on the same job."
      },
      {
        q: "Is StoneGuard® available for honed or polished surfaces?",
        a: "Yes — both. StoneGuard Clear is engineered for polished, glossy stones; it preserves the reflective look and enhances the natural gloss by up to 300%. StoneGuard Satin is engineered for honed and matte stones; it preserves the soft tactile finish while bringing out the depth and color that can wash out in daylight. We confirm the right product based on your slab's finish during the consult.",
        tldr: "Clear for polished. Satin for honed."
      },
      {
        q: "Will StoneGuard® change the look of my stone?",
        a: "Not in a bad way. Once cured, the film is nearly invisible — most clients can't see it unless they're looking at a glancing angle. What it does change is the depth: Clear adds gloss to polished stone, Satin enhances color and variation in honed stone. Both finishes were tuned to look like stone, not like a film over stone.",
        tldr: "Nearly invisible. Enhances depth and color."
      },
      {
        q: "Is StoneGuard® the same as PPF?",
        a: "No. PPF (paint protection film) was developed for car paint — it's flexible, optimized for curved metal panels, and uses adhesives that work against painted surfaces. StoneGuard was developed from the top layer down for stone: the topcoat chemistry, the carrier film, and the gas-permeable adhesive are all specific to porous, calcite-based materials. Despite surface similarities, they aren't interchangeable, and PPF on stone tends to behave unpredictably over time.",
        tldr: "No. PPF is for cars; StoneGuard is for stone."
      },
      {
        q: "Will the seams be visible?",
        a: "Almost never. We template each surface as a single piece wherever possible, and where seams are unavoidable — long runs, L-shapes around an island — we place them along natural breakpoints in the slab and align the cut so the film edge disappears into the stone's veining. You'd have to know exactly where to look.",
        tldr: "Rarely. We hide seams in the veining."
      },
      {
        q: "Will it look glossy or fake?",
        a: "No. Both Clear and Satin were specifically engineered to read as stone, not as plastic. Clear matches the depth of a polished slab; Satin holds the soft, low-sheen feel of honed stone. The film has no orange-peel texture, no visible thickness at the edge, and no shine that doesn't belong.",
        tldr: "No. It reads as stone, not plastic."
      },
      {
        q: "Can I see a sample before I commit?",
        a: "Because StoneGuard is a professional-only product, we don't ship loose samples — they wouldn't represent how the film looks once it's bonded to your specific stone. What we can do is bring sample boards to your in-home consultation and place them on your countertop so you can see Clear and Satin against your actual slab in your actual lighting. That's the only honest comparison.",
        tldr: "Yes — we bring samples to the in-home consultation."
      },
    ]
  },
  {
    cat: "How It Performs",
    blurb: "What it actually stops — chemicals, heat, scratches, wear.",
    items: [
      {
        q: "What chemicals can StoneGuard® protect counter surfaces from?",
        a: "Common kitchen acids and dyes: white vinegar, coffee, citrus, bleach, red wine, tomato — plus a long list of other organic liquids that ruin natural stone. StoneGuard is the sacrificial layer; it takes the chemical hit in place of the slab. Wipe edge spills promptly, and avoid harsh industrial acids on the film, but for everyday kitchen life you can stop policing the countertop.",
        tldr: "Wine, citrus, vinegar, coffee, bleach, tomato — handled."
      },
      {
        q: "Is StoneGuard® heat resistant?",
        a: "StoneGuard is engineered for heat tolerance, but the natural stone underneath can suffer thermal shock from oven-hot items — that's true protected or unprotected. Best practice still applies: use trivets or hot pads under hot cookware when temperatures reach the upper limit of around 420°F. Treat your stone like the natural material it is.",
        tldr: "Yes, up to ~420°F. Still use trivets for oven-hot pans."
      },
      {
        q: "Will the film get damaged over time?",
        a: "StoneGuard is a consumable layer by design — that's the whole point. It absorbs scratches, chemical exposure, and wear so the stone underneath stays exactly as it was the day we installed it. Following the maintenance instructions minimizes wear, and when the film eventually shows its age it can be replaced without affecting the slab. A worn StoneGuard means it did its job.",
        tldr: "It's meant to. The stone underneath stays new."
      },
      {
        q: "Will StoneGuard® peel?",
        a: "Not under normal use. The adhesive system is engineered for long-term bonding to stone, and our installations carry a Limited Lifetime Warranty against bubbling, fading, and natural delamination. Where film occasionally lifts is at exposed edges that get repeatedly soaked — which is why we recommend wiping edge spills promptly. If you ever see lifting, call us; we stand behind the work.",
        tldr: "No, under normal use. Warrantied against natural delamination."
      },
      {
        q: "How long does StoneGuard last?",
        a: "Most of our installations look new well past a decade with normal use. StoneGuard's Performance Guarantee is structured around long service life, and because it's a replaceable consumable, even when the film eventually shows its age the fix is a refresh — not a re-do of your stone. We've returned to clients seven and eight years later and the film still looks tight.",
        tldr: "10+ years with normal use, before refresh is even a question."
      },
      {
        q: "Is it scratch-proof?",
        a: "It's scratch-resistant, not scratch-proof — and the difference matters. The nano-coated topcoat shrugs off everyday contact: dragging plates, sliding small appliances, stacking pans. It is not knife-proof, so we always recommend a cutting board. The film handles the rest of normal kitchen life without showing.",
        tldr: "Resistant, not proof. Use a cutting board."
      },
      {
        q: "What about UV / sunlight from my windows?",
        a: "StoneGuard has built-in UVA/UVB inhibitors and is engineered for installations near windows. The film stays clear and stable under sun exposure and won't yellow over time the way cheaper repurposed films can. If your stone sits in direct afternoon sun, that's exactly the scenario it was built for.",
        tldr: "UV-stable. Won't yellow near windows."
      },
      {
        q: "Will it trap moisture in my stone?",
        a: "No. The top of the film is impermeable — that's how it blocks spills — but the adhesive layer underneath is gas-permeable, so the stone can naturally outgas and breathe. This was a deliberate engineering choice and one of the main reasons StoneGuard works on stone where window film and PPF don't.",
        tldr: "No. The adhesive is gas-permeable; stone breathes."
      },
      {
        q: "Is StoneGuard food-safe?",
        a: "Yes. The film is non-toxic, antimicrobial, and tested to comply with low-VOC indoor air-quality standards. You can prep food directly on it the way you would on any sealed countertop — though we still recommend a cutting board for the sake of the topcoat (and your knives).",
        tldr: "Yes — non-toxic, antimicrobial, low-VOC."
      },
    ]
  },
  {
    cat: "Living With It",
    blurb: "Day-to-day cleaning, what's safe, what to avoid.",
    items: [
      {
        q: "How do I maintain StoneGuard®?",
        a: "Use warm water or a pH-neutral, stone-safe cleaner with a clean microfiber towel, and dry the surface after cleaning to reduce spotting. For tougher residues, use an approved StoneGuard cleaner or surfactant — we'll send you home with everything you need. Avoid abrasive scrubbing pads and powders, and don't use knives directly on the surface. That's the entire maintenance routine.",
        tldr: "Warm water + microfiber. Dry after. That's it."
      },
      {
        q: "What cleaners should I avoid?",
        a: "Skip anything abrasive — scouring pads, powders, magic erasers — and skip harsh industrial chemicals like concentrated acids or solvents. Common household sprays (Windex, 409, etc.) won't damage the film for occasional use, but a stone-safe pH-neutral cleaner is what we recommend day-to-day. When in doubt, warm water and a microfiber wipes most things up.",
        tldr: "No abrasives, no harsh acids. pH-neutral is best."
      },
      {
        q: "Can I cut directly on it?",
        a: "Please don't. The topcoat is scratch-resistant, but a sharp knife under pressure will mark any surface — film, stone, sealer, or otherwise. Use a cutting board, both for the film and for your knives. This is the same advice every stone fabricator gives for unprotected stone, too.",
        tldr: "No. Always use a cutting board."
      },
      {
        q: "Can I put hot pots and pans directly on it?",
        a: "We don't recommend it. StoneGuard tolerates heat up to about 420°F, but the stone underneath can crack from thermal shock independently of the film. A trivet costs five dollars and removes the question entirely. For warm cookware off the stovetop, the film is fine.",
        tldr: "No — use a trivet for oven-hot cookware."
      },
      {
        q: "What happens if I spill red wine and don't notice for hours?",
        a: "Nothing. That's the whole point of StoneGuard. Wine, coffee, balsamic, lemon juice — they sit on the film and wipe up clean whenever you get to it. The stone underneath never sees the spill. The one place to be a little more attentive is the very edge of the counter, where exposed stone meets the film; wipe edge spills when you notice them.",
        tldr: "Nothing. That's literally what it's for."
      },
      {
        q: "Will it stain over time?",
        a: "The film itself is stain-resistant by design and shouldn't discolor under normal use. Some installations near gas cooktops can develop a faint film of cooking residue over years — that's a cleaning issue, not a staining issue, and it wipes off with the recommended StoneGuard surfactant. If you ever see something that looks like permanent discoloration, send us a photo.",
        tldr: "No, under normal use. Cooking residue cleans off."
      },
      {
        q: "Can I use StoneGuard cleaner on the rest of my stone?",
        a: "Yes — the cleaner we provide is pH-neutral and stone-safe, so it's fine on bare marble, granite, or quartzite as well as on the film. Many of our clients use it as their default kitchen counter cleaner across the whole space.",
        tldr: "Yes. It's stone-safe everywhere."
      },
    ]
  },
  {
    cat: "The Install",
    blurb: "What to expect when we show up to do the work.",
    items: [
      {
        q: "Can I install StoneGuard® myself?",
        a: "No — StoneGuard is a professional-only application. Proper adhesion, seamwork, and finish all require certified installation, and DIY isn't recommended (or warrantied). M&T Surface Protectors are certified StoneGuard specialists; we install across NY, NJ, and PA, and we're trained to handle the stone prep, templating, application, and finish work in a single visit.",
        tldr: "No. Pro install only — that's how the warranty works."
      },
      {
        q: "Do fixtures, like the faucet, have to be removed for an installation?",
        a: "Most installs don't require fixtures to be removed. We template carefully around faucets, soap dispensers, and cooktops so the film follows the cutout cleanly. If a fixture is unusually tight or sits flush against the stone, we'll flag that during the consultation and decide together whether removal makes sense — but it's the exception, not the rule.",
        tldr: "Usually no. We template around them."
      },
      {
        q: "How long after installation can the countertops be used?",
        a: "Light use the same day, full use the next morning. The film is touch-dry by the time we leave, but the adhesive needs a few hours to fully bond to the stone — so we ask you to keep liquids and heavy use off the surface overnight. After that, go back to your normal kitchen life.",
        tldr: "Same day for light use. Next morning for full use."
      },
      {
        q: "How long does an install take?",
        a: "Most kitchens are completed in a single day — typically four to eight hours, depending on square footage, stone condition, and how many surfaces are getting protected. Large multi-surface projects (kitchen + bathrooms + bar) can stretch into a second day. We give you a firm time estimate before we start, not at the door.",
        tldr: "One day for most kitchens. We confirm in advance."
      },
      {
        q: "Is the install messy?",
        a: "Less than you'd think. We work with a small amount of water and surfactant during application, and we tape off and protect adjacent cabinetry before we begin. By the time we leave, the kitchen is cleaner than when we arrived — that's a deliberate part of how we work.",
        tldr: "Minimal mess. We protect cabinetry and clean as we go."
      },
      {
        q: "Do I need to be home during the install?",
        a: "Briefly at the beginning so we can walk the surfaces together and confirm scope, and ideally at the end for the final walkthrough — but you don't need to hover. Most clients hand us a key or a code, head to work, and come home to protected stone.",
        tldr: "Briefly at start and end. Not in between."
      },
      {
        q: "How do I prep the kitchen before you arrive?",
        a: "Clear the counters of small appliances, knife blocks, fruit bowls, and anything that lives on the surface. Move heavy items off the cooktop and out of the sink area. We bring everything else: tools, tape, drop cloths, the film itself, and our cleaning kit. If you have specific concerns about a piece of art or stone you want extra protected, tell us beforehand.",
        tldr: "Clear the counters. We bring everything else."
      },
      {
        q: "Can StoneGuard be removed?",
        a: "Yes — the film is removable, which is one of its quietest advantages. If you renovate or sell the home and the next owner doesn't want it, we can remove the film and the stone underneath comes back exactly as it was. It's not permanent, and that's by design.",
        tldr: "Yes. The stone underneath is unchanged."
      },
      {
        q: "Can it be replaced if it gets damaged?",
        a: "Yes — that's the whole model. If the film gets scratched, scorched, or worn after years of use, we remove that section and re-install fresh film. The stone underneath is untouched. Most clients never need this, but knowing it's possible is part of why StoneGuard is the right call for high-end stone.",
        tldr: "Yes. We remove and refresh; stone stays new."
      },
    ]
  },
  {
    cat: "Cost & Booking",
    blurb: "Quotes, scheduling, and what the process feels like.",
    items: [
      {
        q: "How much does StoneGuard cost?",
        a: "We charge a flat rate per square foot, with the exact rate depending on your location, the stone, and whether any restoration is needed before we install. Most kitchen projects fall in a predictable band, and we always send a written quote before any commitment. Reach out with rough dimensions and a photo or two and we'll send back a real number — usually the same day.",
        tldr: "Flat rate per sq ft. Free written quote before you commit."
      },
      {
        q: "Are quotes free?",
        a: "Yes. We do a remote quote based on photos and rough dimensions, and we'll come out for a free in-home consultation when the project is the right fit. There's no obligation either way — many people get a quote, sit on it for a few months, and book later.",
        tldr: "Yes. Remote and in-home consultations are free."
      },
      {
        q: "How far in advance should I book?",
        a: "We're typically booked about a month out, sometimes more during spring and fall. If you have a specific date in mind — a renovation deadline, a move-in, hosting a holiday — reach out as early as you can and we'll do our best to fit it in. We hold a small number of priority slots for time-sensitive projects.",
        tldr: "Usually one month out. Earlier for specific dates."
      },
      {
        q: "Do you do new construction and renovations?",
        a: "Yes — frequently. Many of our installs are coordinated with a kitchen renovation or new build, where the slab is fabricated, set, and then we come in before the homeowner moves back into the space. We work directly with designers, GCs, and stone fabricators when that's helpful.",
        tldr: "Yes. We coordinate with builders, GCs, and fabricators."
      },
      {
        q: "Do you offer financing or payment plans?",
        a: "We accept standard payments and can break larger multi-surface projects into milestone payments tied to the work. We don't currently offer in-house financing, but plenty of clients use a home-improvement card or HELOC for larger jobs — happy to discuss what works for your project.",
        tldr: "Milestone payments on large jobs. No in-house financing."
      },
      {
        q: "What's the consultation process?",
        a: "It usually goes: text or email with rough info → quick remote quote → in-home consultation if it's a fit → written final quote → schedule the install. The whole process from first message to install is typically two to four weeks for a standard kitchen, faster if a slot opens up.",
        tldr: "Message → quote → consult → schedule. 2-4 weeks typical."
      },
    ]
  },
  {
    cat: "Our Promise",
    blurb: "What's covered, for how long, and what happens if something goes wrong.",
    items: [
      {
        q: "What is StoneGuard®'s warranty?",
        a: "StoneGuard comes with a Limited Lifetime Warranty against bubbling, fading, and natural delamination, plus a Performance Guarantee on the protective film itself. Normal wear and tear are excluded — that's the consumable layer doing what it's designed to do. Edge-wicking from exposed edges is also not covered, which is why we ask you to wipe edge spills promptly. Refer to the warranty card we leave with you for full scope and the claim process, and call us anytime if something looks off.",
        tldr: "Limited Lifetime + Performance Guarantee. Wear excluded."
      },
      {
        q: "What's covered, exactly?",
        a: "The warranty covers manufacturing defects, bubbling, fading, and natural delamination — meaning the film coming away from the stone on its own without an external cause. The Performance Guarantee separately covers the film's ability to do its job (resist etching and staining) over its service life. Together they cover the things we and StoneGuard control.",
        tldr: "Defects, bubbling, fading, natural delamination, performance."
      },
      {
        q: "What's NOT covered?",
        a: "Normal wear and tear — small scratches, dulling at high-use spots, eventual replacement need. Edge-wicking caused by repeated soaking at exposed countertop edges. Damage from misuse: cutting directly on the film, harsh industrial chemicals, items above the stated heat threshold. We're transparent about this up front so there are no surprises later.",
        tldr: "Wear, edge-wicking, misuse damage."
      },
      {
        q: "Is the warranty transferable?",
        a: "Warranty terms are tied to the original installation. If you're selling your home, contact us — we'll walk you and the buyer through the specifics so the next owner knows exactly what's protecting their stone, and so you can hand off the documentation cleanly.",
        tldr: "Tied to original install. Call us if you're selling."
      },
      {
        q: "What if something goes wrong?",
        a: "Call or text us. Send photos. We respond same-day on weekdays in almost every case. If it's a warrantable issue, we come back out and make it right at no charge. If it's something outside the warranty (a guest dragged a cast iron skillet, an unusual chemical exposure), we'll still help you understand the options and quote a fair refresh. We're a small team and we stand behind every install we've done.",
        tldr: "Call us. Same-day response. We make it right."
      },
      {
        q: "Do you do follow-up visits?",
        a: "We do a check-in with every install around the 30-day mark, just to confirm everything looks the way it should. After that we're a phone call away. Some clients we've installed for over the years have us back periodically for refreshes or to add coverage to new surfaces — we like staying in touch.",
        tldr: "30-day check-in built in. Available afterward anytime."
      },
    ]
  },
];

// Flatten with global indices for stable keys + search
const ALL_ITEMS = FAQ_DATA.flatMap((sec, sIdx) =>
  sec.items.map((it, iIdx) => ({ ...it, cat: sec.cat, sIdx, iIdx, key: `${sIdx}-${iIdx}`, num: 0 }))
);
// Assign sequential numbers across all questions (for the rail counter)
ALL_ITEMS.forEach((it, i) => { it.num = i + 1; });

const TOTAL_Q = ALL_ITEMS.length;
const CATS = FAQ_DATA.map(s => s.cat);

// ============================================================
// HERO
// ============================================================
function FaqHero() {
  return (
    <section style={{
      paddingTop: 180, paddingBottom: 100,
      position: "relative",
      overflow: "hidden",
      background: `
        radial-gradient(ellipse 110% 70% at 80% 15%, rgba(232,212,168,0.38) 0%, transparent 55%),
        radial-gradient(ellipse 90% 60% at 12% 90%, rgba(107,20,22,0.10) 0%, transparent 55%),
        radial-gradient(ellipse 70% 50% at 50% 50%, rgba(59,90,74,0.05) 0%, transparent 60%),
        linear-gradient(180deg, var(--cream) 0%, var(--bone) 55%, var(--bone-2) 100%)
      `,
      borderBottom: "1px solid var(--line)",
    }}>
      {/* Drifting marble vein layer */}
      <svg aria-hidden="true" style={{
        position: "absolute", inset: 0, width: "100%", height: "100%",
        opacity: 0.13, pointerEvents: "none",
      }} viewBox="0 0 1440 800" preserveAspectRatio="none">
        <defs>
          <linearGradient id="vein-a" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor="#6B1416" stopOpacity="0"/>
            <stop offset="50%" stopColor="#6B1416" stopOpacity="0.8"/>
            <stop offset="100%" stopColor="#6B1416" stopOpacity="0"/>
          </linearGradient>
          <linearGradient id="vein-b" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor="#8B5A2B" stopOpacity="0"/>
            <stop offset="50%" stopColor="#8B5A2B" stopOpacity="0.7"/>
            <stop offset="100%" stopColor="#8B5A2B" stopOpacity="0"/>
          </linearGradient>
        </defs>
        <path d="M-50 220 Q 300 140, 600 250 T 1200 200 T 1500 320" stroke="url(#vein-a)" strokeWidth="1.4" fill="none">
          <animate attributeName="d" dur="22s" repeatCount="indefinite"
            values="M-50 220 Q 300 140, 600 250 T 1200 200 T 1500 320;
                    M-50 240 Q 300 180, 600 220 T 1200 240 T 1500 280;
                    M-50 220 Q 300 140, 600 250 T 1200 200 T 1500 320"/>
        </path>
        <path d="M-50 540 Q 350 460, 700 540 T 1300 480 T 1500 600" stroke="url(#vein-b)" strokeWidth="0.9" fill="none">
          <animate attributeName="d" dur="28s" repeatCount="indefinite"
            values="M-50 540 Q 350 460, 700 540 T 1300 480 T 1500 600;
                    M-50 520 Q 350 500, 700 510 T 1300 520 T 1500 560;
                    M-50 540 Q 350 460, 700 540 T 1300 480 T 1500 600"/>
        </path>
      </svg>

      <div className="container" style={{ position: "relative", zIndex: 1 }}>
        <LineEyebrow style={{ marginBottom: 56 }}>
          M&amp;T · Frequently asked
        </LineEyebrow>
        <h1 className="serif" style={{
          fontSize: "clamp(48px, 7.4vw, 124px)",
          lineHeight: 0.96,
          letterSpacing: "-0.025em",
          maxWidth: 1280,
          marginBottom: 72,
          textWrap: "balance",
        }}>
          <WordReveal text="The questions we get," />
          <br/>
          <span style={{
            background: "linear-gradient(95deg, #6B1416 0%, #8B1C1E 35%, #9B4A2E 75%, #8B5A2B 100%)",
            WebkitBackgroundClip: "text",
            backgroundClip: "text",
            color: "transparent",
            fontStyle: "italic",
          }}>
            <WordReveal text="answered honestly." delay={400} />
          </span>
        </h1>

        <Reveal delay={900}>
          {/* meta line */}
          <div className="mono" style={{
            display: "flex", alignItems: "center", gap: 14,
            fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase",
            color: "var(--mute)",
            marginBottom: 28,
            flexWrap: "wrap",
          }}>
            <span>50+ Questions</span>
            <span style={{ width: 4, height: 4, borderRadius: 99, background: "var(--mute)", opacity: 0.5 }}/>
            <span>{CATS.length} Chapters</span>
            <span style={{ width: 4, height: 4, borderRadius: 99, background: "var(--mute)", opacity: 0.5 }}/>
            <span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}>
              <span style={{
                width: 6, height: 6, borderRadius: 99, background: "#3B5A4A",
                animation: "faq-pulse 2.2s cubic-bezier(.4,.0,.6,1) infinite",
              }}/>
              Reviewed April 2026
            </span>
          </div>

          {/* The actually-useful kicker — what people most want to know */}
          <div className="mono" style={{
            fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase",
            color: "var(--ink-2)",
            marginBottom: 18,
          }}>
            What most people ask first
          </div>

          <div className="faq-hero-shortcuts" style={{
            display: "grid",
            gridTemplateColumns: "1fr 1fr 1fr",
            gap: 14,
          }}>
            <Shortcut
              num="01"
              kicker="The price question"
              question="How much does StoneGuard cost?"
              tldr="Flat rate per sq ft. Free written quote — usually same day."
              jumpKey="5-0"
              jumpCat="Cost & Booking"
              accent="#6B1416"
            />
            <Shortcut
              num="02"
              kicker="The fear question"
              question="Will my stone look fake or plastic?"
              tldr="No. Engineered to read as stone, not as film over stone."
              jumpKey="1-5"
              jumpCat="Looks & Finish"
              accent="#8B5A2B"
            />
            <Shortcut
              num="03"
              kicker="The trust question"
              question="What's the warranty if something goes wrong?"
              tldr="Limited Lifetime + Performance Guarantee. We come back."
              jumpKey="6-0"
              jumpCat="Our Promise"
              accent="#3B5A4A"
            />
          </div>
        </Reveal>
      </div>

      <style>{`
        @media (max-width: 980px){
          .faq-hero-shortcuts{ grid-template-columns: 1fr !important; }
        }
        @keyframes faq-pulse {
          0%,100% { opacity: 0.4; }
          50% { opacity: 1; }
        }
      `}</style>
    </section>
  );
}

// One "most-asked" shortcut card. Click jumps to that question in the index.
function Shortcut({ num, kicker, question, tldr, jumpKey, jumpCat, accent }) {
  const [hover, setHover] = useFS(false);
  const onClick = () => {
    window.dispatchEvent(new CustomEvent("faq:jump", { detail: { key: jumpKey, cat: jumpCat } }));
  };
  return (
    <button
      onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        appearance: "none", border: "1px solid var(--line)",
        background: hover ? "rgba(255,255,255,0.85)" : "rgba(255,255,255,0.55)",
        backdropFilter: "blur(8px)",
        WebkitBackdropFilter: "blur(8px)",
        padding: "26px 26px 22px",
        textAlign: "left",
        cursor: "pointer",
        display: "flex", flexDirection: "column",
        gap: 16,
        minHeight: 220,
        transition: "background .35s ease, transform .35s ease, border-color .35s ease",
        transform: hover ? "translateY(-2px)" : "translateY(0)",
        borderColor: hover ? accent : "var(--line)",
        position: "relative",
        overflow: "hidden",
        fontFamily: "inherit",
        color: "inherit",
      }}
    >
      {/* corner index */}
      <div style={{
        display: "flex", alignItems: "center", justifyContent: "space-between",
      }}>
        <div className="mono" style={{
          fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase",
          color: accent,
          fontVariantNumeric: "tabular-nums",
        }}>
          {num} · {kicker}
        </div>
        <svg width="18" height="12" viewBox="0 0 18 12" style={{
          transform: hover ? "translateX(4px)" : "translateX(0)",
          transition: "transform .35s ease",
          color: accent,
        }}>
          <path d="M1 6 L16 6 M11 1 L16 6 L11 11" stroke="currentColor" strokeWidth="1.2" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </div>

      <div className="serif" style={{
        fontSize: "clamp(20px, 1.7vw, 24px)",
        lineHeight: 1.18,
        letterSpacing: "-0.015em",
        color: "var(--ink)",
        textWrap: "balance",
        flex: 1,
      }}>
        {question}
      </div>

      <div style={{
        fontSize: 13, lineHeight: 1.5,
        color: "var(--ink-2)",
        fontStyle: "italic",
        borderTop: "1px solid var(--line)",
        paddingTop: 14,
      }}>
        {tldr}
      </div>
    </button>
  );
}

function StatTile({ kicker, value, suffix, accent, live }) {
  return (
    <div style={{
      padding: "24px 24px",
      background: "rgba(255,255,255,0.6)",
      border: "1px solid var(--line)",
      borderTop: `3px solid ${accent}`,
      backdropFilter: "blur(8px)",
      WebkitBackdropFilter: "blur(8px)",
      display: "flex", flexDirection: "column", justifyContent: "space-between",
      minHeight: 170,
      position: "relative",
    }}>
      <div className="mono" style={{
        fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase",
        color: "var(--mute)",
        display: "flex", alignItems: "center", gap: 8,
      }}>
        {live && <span style={{
          width: 6, height: 6, borderRadius: 99, background: accent,
          animation: "faq-pulse 2.2s cubic-bezier(.4,.0,.6,1) infinite",
        }}/>}
        {kicker}
      </div>
      <div className="serif" style={{
        fontSize: 56,
        lineHeight: 1,
        letterSpacing: "-0.03em",
        color: accent,
        fontVariantNumeric: "tabular-nums",
      }}>
        {value}
        {suffix && (
          <span className="mono" style={{
            fontSize: 11, letterSpacing: "0.2em", color: "var(--mute)",
            marginLeft: 8, verticalAlign: "middle",
          }}>{suffix}</span>
        )}
      </div>
      <style>{`
        @keyframes faq-pulse {
          0%,100% { opacity: 0.4; }
          50% { opacity: 1; }
        }
      `}</style>
    </div>
  );
}

// ============================================================
// THE INDEX — three-column on desktop:
//   [chapter rail] [question list] [stage / answer panel]
// On narrower screens, becomes a single-column inline accordion.
// ============================================================
function FaqIndex() {
  const [activeKey, setActiveKey] = useFS(FT.openByDefault === "first" ? "0-0" : null);
  const [activeCat, setActiveCat] = useFS(CATS[0]);
  const [query, setQuery] = useFS("");
  const [isMobile, setIsMobile] = useFS(false);

  useFE(() => {
    const check = () => setIsMobile(window.matchMedia("(max-width: 1080px)").matches);
    check();
    window.addEventListener("resize", check);
    return () => window.removeEventListener("resize", check);
  }, []);

  // Listen for shortcut clicks from the hero — open the question and scroll into view.
  useFE(() => {
    const onJump = (e) => {
      const { key, cat } = e.detail || {};
      if (cat) setActiveCat(cat);
      if (key) setActiveKey(key);
      setQuery("");
      const el = document.getElementById("faq-index");
      if (el) {
        const top = el.getBoundingClientRect().top + window.scrollY - 40;
        window.scrollTo({ top, behavior: "smooth" });
      }
    };
    window.addEventListener("faq:jump", onJump);
    return () => window.removeEventListener("faq:jump", onJump);
  }, []);

  const filtered = useFM(() => {
    const q = query.trim().toLowerCase();
    if (!q) return ALL_ITEMS;
    return ALL_ITEMS.filter(it => (it.q + " " + it.a).toLowerCase().includes(q));
  }, [query]);

  // When searching, ignore chapter filter; otherwise show only active cat
  const visible = useFM(() => {
    if (query.trim()) return filtered;
    return filtered.filter(it => it.cat === activeCat);
  }, [filtered, activeCat, query]);

  const activeItem = useFM(
    () => ALL_ITEMS.find(it => it.key === activeKey) || null,
    [activeKey]
  );

  return (
    <section id="faq-index" style={{ padding: "100px 0 140px", background: "var(--bone)" }}>
      <div className="container">
        <div className="faq-shell" style={{
          display: "grid",
          gridTemplateColumns: isMobile ? "1fr" : "260px 1fr 1fr",
          gap: isMobile ? 48 : 56,
          alignItems: "start",
        }}>

          {/* COLUMN 1 — chapter rail (framed as a navigation card) */}
          <aside className="faq-rail" style={{
            position: isMobile ? "static" : "sticky",
            top: 110,
            background: "#FAF5EE",
            border: "1px solid var(--line)",
            borderRadius: 4,
            padding: "22px 22px 26px",
            boxShadow: "0 1px 0 rgba(20,20,18,0.04), 0 24px 40px -28px rgba(20,20,18,0.18)",
          }}>
            <div style={{
              display: "flex", alignItems: "center", justifyContent: "space-between",
              marginBottom: 18, paddingBottom: 14,
              borderBottom: "1px solid var(--line)",
            }}>
              <div className="mono" style={{
                fontSize: 10, letterSpacing: "0.24em", textTransform: "uppercase",
                color: "var(--ink)",
              }}>
                The Index
              </div>
              <div className="mono" style={{
                fontSize: 9, letterSpacing: "0.18em", textTransform: "uppercase",
                color: "var(--mute)", fontVariantNumeric: "tabular-nums",
              }}>
                {String(FAQ_DATA.reduce((n, s) => n + s.items.length, 0)).padStart(2, "0")} entries
              </div>
            </div>

            <nav style={{ display: "flex", flexDirection: "column", marginBottom: 28 }}>
              {CATS.map((c, i) => {
                const isActive = !query.trim() && c === activeCat;
                const sec = FAQ_DATA[i];
                const count = sec.items.length;
                const t = themeFor(c);
                const isLast = i === CATS.length - 1;
                return (
                  <button
                    key={c}
                    onClick={() => { setActiveCat(c); setQuery(""); }}
                    className="faq-cat"
                    style={{
                      display: "grid",
                      gridTemplateColumns: "14px auto 1fr auto",
                      alignItems: "center",
                      gap: 10,
                      width: "100%",
                      textAlign: "left",
                      padding: "14px 12px",
                      margin: "0 -12px",
                      borderBottom: isLast ? "none" : "1px solid rgba(20,20,18,0.08)",
                      cursor: "pointer",
                      transition: "background .3s ease",
                      background: isActive ? t.tint : "transparent",
                      borderLeft: isActive ? `2px solid ${t.accent}` : "2px solid transparent",
                    }}
                  >
                    {/* Color dot — fades to filled when active */}
                    <span style={{
                      width: 10, height: 10, borderRadius: 99,
                      background: isActive ? t.accent : "transparent",
                      border: `1.5px solid ${isActive ? t.accent : t.accent + "66"}`,
                      transition: "background .3s ease, border-color .3s ease, transform .3s ease",
                      transform: isActive ? "scale(1.15)" : "scale(1)",
                    }}/>
                    <span className="mono" style={{
                      fontSize: 10, letterSpacing: "0.22em",
                      color: isActive ? t.accent : "var(--mute)",
                      transition: "color .25s ease",
                      fontVariantNumeric: "tabular-nums",
                    }}>
                      {String(i + 1).padStart(2, "0")}
                    </span>
                    <span className="serif" style={{
                      fontSize: 22,
                      letterSpacing: "-0.01em",
                      lineHeight: 1.15,
                      fontStyle: isActive ? "italic" : "normal",
                      color: isActive ? t.accent : "var(--ink)",
                      transition: "color .25s ease, font-style .25s ease",
                    }}>
                      {c}
                    </span>
                    <span className="mono" style={{
                      fontSize: 10, letterSpacing: "0.18em",
                      color: isActive ? t.accent : "var(--mute)",
                      fontVariantNumeric: "tabular-nums",
                      transition: "color .25s ease",
                    }}>
                      {String(count).padStart(2, "0")}
                    </span>
                  </button>
                );
              })}
            </nav>

            {/* Search */}
            {FT.showSearch !== false && (
              <div style={{
                paddingTop: 18,
                borderTop: "1px solid var(--line)",
              }}>
                <div className="mono" style={{
                  fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase",
                  color: "var(--mute)", marginBottom: 12,
                }}>
                  Search
                </div>
                <div style={{
                  display: "flex", alignItems: "center", gap: 10,
                  borderBottom: `1px solid ${query ? "var(--ink)" : "var(--line)"}`,
                  paddingBottom: 10,
                  transition: "border-color .2s ease",
                }}>
                  <svg width="14" height="14" viewBox="0 0 14 14" fill="none" style={{ flexShrink: 0, opacity: 0.5 }}>
                    <circle cx="6" cy="6" r="4.5" stroke="currentColor" strokeWidth="1.2"/>
                    <path d="M9.5 9.5L13 13" stroke="currentColor" strokeWidth="1.2"/>
                  </svg>
                  <input
                    value={query}
                    onChange={e => setQuery(e.target.value)}
                    placeholder="Try 'wine' or 'warranty'"
                    style={{
                      flex: 1, border: "none", outline: "none",
                      background: "transparent", fontSize: 14, padding: 0,
                    }}
                  />
                  {query && (
                    <button onClick={() => setQuery("")} className="mono" style={{
                      fontSize: 10, letterSpacing: "0.18em", color: "var(--mute)",
                      textTransform: "uppercase",
                    }}>
                      Clear
                    </button>
                  )}
                </div>
                <div className="mono" style={{
                  fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase",
                  color: "var(--mute)", marginTop: 12,
                  fontVariantNumeric: "tabular-nums",
                  minHeight: 14,
                }}>
                  {query ? `${filtered.length} match${filtered.length === 1 ? "" : "es"}` : ""}
                </div>
              </div>
            )}
          </aside>

          {/* COLUMN 2 — question list */}
          <div className="faq-list">
            {!query.trim() && (() => {
              const t = themeFor(activeCat);
              return (
                <div style={{
                  marginBottom: 36,
                  paddingBottom: 24,
                  borderBottom: "1px solid var(--line)",
                }}>
                  <div className="mono" style={{
                    fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase",
                    color: "var(--mute)", marginBottom: 12,
                  }}>
                    {String(CATS.indexOf(activeCat) + 1).padStart(2, "0")} · Chapter
                  </div>
                  <h2 className="serif" style={{
                    fontSize: 36, letterSpacing: "-0.02em", lineHeight: 1.05,
                    marginBottom: 12,
                    color: "var(--ink)",
                  }}>
                    {activeCat}
                  </h2>
                  <p style={{
                    fontSize: 15, lineHeight: 1.6, color: "var(--mute)",
                    maxWidth: 460,
                  }}>
                    {FAQ_DATA.find(s => s.cat === activeCat)?.blurb}
                  </p>
                </div>
              );
            })()}

            {query.trim() && (
              <div style={{ marginBottom: 28 }}>
                <div className="mono" style={{
                  fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase",
                  color: "var(--mute)", marginBottom: 8,
                }}>
                  Searching · {filtered.length} match{filtered.length === 1 ? "" : "es"}
                </div>
                <h2 className="serif" style={{
                  fontSize: 36, letterSpacing: "-0.02em", lineHeight: 1.05,
                }}>
                  "{query}"
                </h2>
              </div>
            )}

            {visible.length === 0 && (
              <div style={{ padding: "60px 0", color: "var(--mute)" }}>
                <div className="serif" style={{ fontSize: 28, marginBottom: 8, color: "var(--ink)" }}>
                  Nothing matches that.
                </div>
                <p style={{ fontSize: 15, lineHeight: 1.6, maxWidth: 380 }}>
                  Try a different word — or scroll down and ask us directly.
                </p>
              </div>
            )}

            <ul style={{ listStyle: "none", padding: 0, margin: 0 }}>
              {visible.map((it) => (
                <FaqQuestion
                  key={it.key}
                  item={it}
                  isActive={activeKey === it.key}
                  isMobile={isMobile}
                  query={query}
                  onActivate={() => setActiveKey(activeKey === it.key && isMobile ? null : it.key)}
                />
              ))}
            </ul>
          </div>

          {/* COLUMN 3 — stage / reading panel (desktop only) */}
          {!isMobile && (
            <div className="faq-stage" style={{
              position: "sticky",
              top: 110,
            }}>
              <FaqStage item={activeItem} query={query} />
            </div>
          )}
        </div>
      </div>

      <style>{`
        .faq-cat:hover { padding-left: 6px !important; }
        .faq-cat:hover .serif { color: var(--ink) !important; }
      `}</style>
    </section>
  );
}

// --- One row in the question list ---
function FaqQuestion({ item, isActive, isMobile, query, onActivate }) {
  const [hover, setHover] = useFS(false);
  // Mobile expand uses the CSS grid-template-rows: 0fr / 1fr trick — no JS
  // height measurement needed, transitions reliably between collapsed/expanded.
  const expanded = isMobile && isActive;

  const numStr = String(item.num).padStart(2, "0");

  return (
    <li
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        borderBottom: "1px solid var(--line)",
        position: "relative",
      }}
    >
      {/* chapter-color scrub line — drawn when active */}
      <div style={{
        position: "absolute", bottom: -1, left: 0,
        height: 1,
        background: themeFor(item.cat).accent,
        width: isActive ? "100%" : "0%",
        transition: "width 800ms cubic-bezier(.2,.7,.2,1)",
      }}/>
      {/* left ribbon — chapter color flag, slides in when active */}
      <div style={{
        position: "absolute", left: -16, top: 18, bottom: 18,
        width: 3,
        background: themeFor(item.cat).accent,
        opacity: isActive ? 1 : 0,
        transform: isActive ? "translateX(0)" : "translateX(-6px)",
        transition: "opacity .35s ease, transform .35s cubic-bezier(.2,.7,.2,1)",
      }}/>

      <button
        onClick={onActivate}
        style={{
          display: "grid",
          gridTemplateColumns: "44px 1fr 24px",
          gap: 16,
          alignItems: "start",
          width: "100%",
          textAlign: "left",
          padding: "22px 0",
          background: "transparent",
          color: "inherit",
          cursor: "pointer",
        }}
      >
        <div className="mono" style={{
          fontSize: 11, letterSpacing: "0.22em",
          color: isActive ? themeFor(item.cat).accent : "var(--mute)",
          paddingTop: 6,
          fontVariantNumeric: "tabular-nums",
          transition: "color .3s ease",
          display: "flex", alignItems: "center", gap: 8,
        }}>
          <span style={{
            width: 6, height: 6, borderRadius: 99,
            background: isActive ? themeFor(item.cat).accent : themeFor(item.cat).accent + "55",
            transform: isActive ? "scale(1.4)" : "scale(1)",
            transition: "transform .3s ease, background .3s ease",
            display: "inline-block",
          }}/>
          {numStr}
        </div>

        <div>
          <div className="serif" style={{
            fontSize: "clamp(20px, 1.6vw, 24px)",
            lineHeight: 1.25,
            letterSpacing: "-0.01em",
            color: isActive ? themeFor(item.cat).accent : (hover ? "var(--ink)" : "var(--ink-2)"),
            fontStyle: isActive ? "italic" : "normal",
            transition: "color .3s ease, font-style .3s ease",
            textWrap: "balance",
          }}>
            {query ? <Highlighted text={item.q} q={query}/> : item.q}
          </div>

          {/* Slim TLDR preview line — appears on hover when not active */}
          <div style={{
            maxHeight: hover && !isActive ? 24 : 0,
            opacity: hover && !isActive ? 1 : 0,
            overflow: "hidden",
            transition: "max-height 350ms cubic-bezier(.2,.7,.2,1), opacity 250ms ease",
          }}>
            <div className="mono" style={{
              fontSize: 10, letterSpacing: "0.16em", textTransform: "uppercase",
              color: "var(--mute)",
              marginTop: 8,
            }}>
              {item.tldr}
            </div>
          </div>
        </div>

        {/* Glyph: arrow on desktop (it slides into the stage),
            plus/minus on mobile (it expands inline) */}
        <div style={{
          width: 24, height: 24,
          marginTop: 4,
          position: "relative",
          justifySelf: "end",
        }}>
          {isMobile ? (
            <>
              <span style={{
                position: "absolute", top: "50%", left: 0, right: 0,
                height: 1, background: isActive ? "var(--maroon)" : "var(--ink)",
                transform: "translateY(-0.5px)",
                transition: "background .3s ease",
              }}/>
              <span style={{
                position: "absolute", left: "50%", top: 0, bottom: 0,
                width: 1, background: isActive ? "var(--maroon)" : "var(--ink)",
                transform: `translateX(-0.5px) rotate(${isActive ? 90 : 0}deg)`,
                transformOrigin: "center",
                transition: "transform .5s cubic-bezier(.2,.7,.2,1), background .3s ease",
              }}/>
            </>
          ) : (
            <svg width="20" height="20" viewBox="0 0 20 20" fill="none" style={{
              transform: isActive ? "translateX(4px)" : (hover ? "translateX(2px)" : "translateX(0)"),
              transition: "transform .35s cubic-bezier(.2,.7,.2,1)",
            }}>
              <path d="M3 10h14m0 0L11 4m6 6l-6 6"
                stroke={isActive ? themeFor(item.cat).accent : (hover ? "var(--ink)" : "var(--mute)")}
                strokeWidth="1.3"/>
            </svg>
          )}
        </div>
      </button>

      {/* Mobile-only inline answer — uses grid-template-rows trick for reliable expand */}
      <div style={{
        display: "grid",
        gridTemplateRows: expanded ? "1fr" : "0fr",
        transition: "grid-template-rows 600ms cubic-bezier(.2,.7,.2,1)",
      }}>
        <div style={{ overflow: "hidden", minHeight: 0 }}>
          <div style={{ paddingBottom: 32, paddingLeft: 60, paddingRight: 24 }}>
            <p style={{
              fontSize: 16, lineHeight: 1.65,
              color: "var(--ink-2)",
              opacity: expanded ? 1 : 0,
              transform: expanded ? "translateY(0)" : "translateY(8px)",
              transition: "opacity 600ms ease 150ms, transform 600ms cubic-bezier(.2,.7,.2,1) 150ms",
            }}>
              {query ? <Highlighted text={item.a} q={query}/> : item.a}
            </p>
          </div>
        </div>
      </div>
    </li>
  );
}

// --- The right-side stage on desktop. Holds the active answer with
//     a key-based crossfade so switching questions feels like a page turn.
function FaqStage({ item, query }) {
  const [renderKey, setRenderKey] = useFS(item ? item.key : "empty");
  const [content, setContent] = useFS(item);
  const [phase, setPhase] = useFS("in"); // in | out

  // Crossfade when item changes
  useFE(() => {
    if (!item) {
      setPhase("out");
      const t = setTimeout(() => { setContent(null); setRenderKey("empty"); setPhase("in"); }, 240);
      return () => clearTimeout(t);
    }
    if (item.key === renderKey) return;
    setPhase("out");
    const t = setTimeout(() => {
      setContent(item);
      setRenderKey(item.key);
      setPhase("in");
    }, 240);
    return () => clearTimeout(t);
  }, [item]);

  return (
    <div style={{
      background: "var(--cream)",
      border: "1px solid var(--line)",
      borderRadius: 2,
      padding: "44px 44px 40px",
      minHeight: 480,
      position: "relative",
      overflow: "hidden",
      boxShadow: "0 30px 60px -30px rgba(20,20,18,0.18)",
    }}>
      {/* corner serial */}
      <div className="mono" style={{
        position: "absolute", top: 20, right: 24,
        fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase",
        color: "var(--mute)",
        fontVariantNumeric: "tabular-nums",
      }}>
        {content ? `${String(content.num).padStart(2, "0")} / ${String(TOTAL_Q).padStart(2, "0")}` : "—"}
      </div>

      {/* slow-draw corner mark — tonal, not maroon */}
      <svg
        width="44" height="44" viewBox="0 0 44 44"
        style={{ position: "absolute", top: 18, left: 18, opacity: 0.45 }}
      >
        <path d="M2 22 L22 2" stroke="var(--ink-2)" strokeWidth="1"
          strokeDasharray="40"
          strokeDashoffset={phase === "in" ? "0" : "40"}
          style={{ transition: "stroke-dashoffset 700ms ease 80ms" }}
        />
      </svg>

      <div style={{
        opacity: phase === "in" ? 1 : 0,
        transform: phase === "in" ? "translateY(0)" : "translateY(10px)",
        transition: "opacity 380ms ease, transform 460ms cubic-bezier(.2,.7,.2,1)",
        paddingTop: 32,
      }}>
        {!content && (
          <div style={{ paddingTop: 60, color: "var(--mute)" }}>
            <div className="serif" style={{
              fontSize: 32, lineHeight: 1.15, color: "var(--ink)",
              marginBottom: 16, letterSpacing: "-0.01em",
            }}>
              Pick a question.
            </div>
            <p style={{ fontSize: 15, lineHeight: 1.65, maxWidth: 360 }}>
              Click any question on the left and the answer will land here.
            </p>
          </div>
        )}

        {content && (
          <>
            <div className="mono" style={{
              fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase",
              color: themeFor(content.cat).accent,
              marginBottom: 18,
              display: "flex", alignItems: "center", gap: 8,
            }}>
              <span style={{
                width: 8, height: 8, borderRadius: 99,
                background: themeFor(content.cat).accent,
                display: "inline-block",
              }}/>
              {content.cat}
            </div>

            <h3 className="serif" style={{
              fontSize: "clamp(28px, 2.4vw, 36px)",
              lineHeight: 1.15,
              letterSpacing: "-0.02em",
              marginBottom: 28,
              textWrap: "balance",
              color: themeFor(content.cat).deep,
            }}>
              {query ? <Highlighted text={content.q} q={query}/> : content.q}
            </h3>

            <div style={{
              borderTop: "1px solid var(--line)",
              paddingTop: 24,
              marginBottom: 28,
            }}>
              <p style={{
                fontSize: 16, lineHeight: 1.7,
                color: "var(--ink-2)",
              }}>
                {query ? <Highlighted text={content.a} q={query}/> : content.a}
              </p>
            </div>

            <div style={{
              display: "flex",
              alignItems: "baseline",
              justifyContent: "space-between",
              gap: 16,
              paddingTop: 20,
              borderTop: "1px solid var(--line)",
            }}>
              <div className="mono" style={{
                fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase",
                color: "var(--mute)",
              }}>
                The short version
              </div>
              <div className="serif" style={{
                fontSize: 18, fontStyle: "italic",
                color: themeFor(content.cat).accent,
                textAlign: "right",
                maxWidth: "70%",
                lineHeight: 1.35,
              }}>
                {content.tldr}
              </div>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

// Inline highlight
function Highlighted({ text, q }) {
  const needle = q.trim();
  if (!needle) return text;
  const re = new RegExp(`(${needle.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`, "ig");
  const split = String(text).split(re);
  return split.map((p, i) =>
    re.test(p) ? (
      <mark key={i} style={{
        background: "rgba(107,20,22,0.13)",
        color: "var(--maroon)",
        padding: "0 2px",
        borderRadius: 2,
      }}>{p}</mark>
    ) : <span key={i}>{p}</span>
  );
}

// ============================================================
// CLOSER — "still got questions?"
// ============================================================
function FaqCloser({ onInquire }) {
  const prompts = ["red wine", "warranty", "honed marble", "the install", "edge details", "your kitchen"];
  return (
    <section id="ask" style={{
      background: "var(--black)",
      color: "var(--bone)",
      padding: "160px 0",
      position: "relative",
      overflow: "hidden",
    }}>
      <div className="serif" aria-hidden="true" style={{
        position: "absolute",
        right: -40, bottom: -160,
        fontSize: 720, lineHeight: 1,
        color: "var(--maroon)",
        opacity: 0.18,
        pointerEvents: "none",
        fontStyle: "italic",
      }}>
        ?
      </div>

      <div className="container" style={{ position: "relative", zIndex: 1 }}>
        <div style={{
          display: "grid",
          gridTemplateColumns: "1fr 1fr",
          gap: 80, alignItems: "end",
        }} className="faq-closer-grid">
          <div>
            <LineEyebrow style={{ marginBottom: 40, color: "rgba(245,242,237,0.65)" }}>
              Still wondering?
            </LineEyebrow>
            <h2 className="serif" style={{
              fontSize: "clamp(40px, 5.4vw, 80px)",
              lineHeight: 1.02,
              letterSpacing: "-0.022em",
              maxWidth: 780,
            }}>
              <WordReveal text="Ask us about" />
              {" "}
              <span style={{ color: "var(--bronze)", fontStyle: "italic" }}>
                <Typewriter words={prompts} typeSpeed={90} deleteSpeed={45} holdMs={1400}/>
              </span>
            </h2>
          </div>

          <div>
            <Reveal delay={200}>
              <p style={{
                fontSize: 18, lineHeight: 1.6,
                color: "rgba(245,242,237,0.78)",
                maxWidth: 480,
                marginBottom: 36,
              }}>
                Send us a photo of your stone, a few details about your kitchen, and the one question that's been bugging you. Most replies come back the same day, and there's no obligation either way.
              </p>
              <div style={{ display: "flex", gap: 16, flexWrap: "wrap" }}>
                <button onClick={onInquire} className="btn" style={{
                  background: "var(--bone)", color: "var(--ink)",
                }}>
                  Ask a question
                  <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                    <path d="M1 7h12m0 0L7 1m6 6L7 13" stroke="currentColor" strokeWidth="1.3"/>
                  </svg>
                </button>
                <a href="mailto:sales@mtsurfaceprotectors.com" className="btn" style={{
                  border: "1px solid rgba(245,242,237,0.3)",
                  color: "var(--bone)",
                }}>
                  sales@mtsurfaceprotectors.com
                </a>
              </div>

              <div className="mono" style={{
                fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase",
                color: "rgba(245,242,237,0.5)",
                marginTop: 32,
                lineHeight: 1.9,
              }}>
                <div>Phone · +1 (908) 866-1919</div>
                <div>Service area · NY · NJ · PA</div>
              </div>
            </Reveal>
          </div>
        </div>
      </div>

      <style>{`
        @media (max-width: 860px){
          .faq-closer-grid{ grid-template-columns: 1fr !important; gap: 40px !important; }
        }
      `}</style>
    </section>
  );
}

// ============================================================
// FOOTER
// ============================================================
function FaqFooter() {
  return (
    <footer style={{
      background: "var(--bone)",
      borderTop: "1px solid var(--line)",
      padding: "48px 0",
    }}>
      <div className="container" style={{
        display: "flex", justifyContent: "space-between", alignItems: "center",
        gap: 24, flexWrap: "wrap",
      }}>
        <div className="mono" style={{ fontSize: 10, letterSpacing: "0.2em", textTransform: "uppercase", color: "var(--mute)" }}>
          © 2026 M&amp;T Surface Protectors LLC
        </div>
        <div style={{ display: "flex", gap: 28 }}>
          {[
            { label: "Home", href: "index.html" },
            { label: "Services", href: "services.html" },
            { label: "Work", href: "work.html" },
            { label: "Learn", href: "learn.html" },
          ].map(l => (
            <a key={l.label} href={l.href} className="mono" style={{
              fontSize: 10, letterSpacing: "0.2em", textTransform: "uppercase", color: "var(--ink-2)",
            }}>{l.label}</a>
          ))}
        </div>
      </div>
    </footer>
  );
}

// ============================================================
// APP
// ============================================================
function FaqApp() {
  const [wizardOpen, setWizardOpen] = useFS(false);
  const onInquire = () => setWizardOpen(true);
  return (
    <>
      <Nav onInquire={onInquire}/>
      <FaqHero/>
      <FaqIndex/>
      <FaqCloser onInquire={onInquire}/>
      <FaqFooter/>
      {typeof Wizard !== "undefined" && (
        <Wizard open={wizardOpen} onClose={() => setWizardOpen(false)}/>
      )}
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<FaqApp/>);
