  :root{
    --font-display:'Cormorant Garamond',Georgia,'Times New Roman',serif;
    --font-body:'Karla','Helvetica Neue',Arial,sans-serif;
    --brown:#1a1410;
    --brown-soft:#2b2118;
    --olive:#c9963f;
    --olive-deep:#7d5a1e;
    --olive-deeper:#5c4117;
    --cream:#f7f2e7;
    --cream-dim:#ede4d0;
    --gold:#d9b25e;
    --gold-soft:rgba(217,178,94,.35);
    --line:rgba(26,20,16,.14);
    --line-light:rgba(247,242,231,.18);
  }
  *{box-sizing:border-box;margin:0;padding:0}
  html{scroll-behavior:smooth}

  /* Visible focus rings for keyboard users (mouse clicks stay clean) */
  a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{
    outline:3px solid var(--olive-deep);outline-offset:3px;border-radius:3px;
  }
  header a:focus-visible,header button:focus-visible,.hero a:focus-visible,.hero button:focus-visible,.why a:focus-visible,
  footer a:focus-visible,footer button:focus-visible,.final a:focus-visible,.final button:focus-visible{outline-color:#e8cf9c}

  /* Skip link — first tab stop, hidden until focused */
  .skip-link{
    position:absolute;left:16px;top:-60px;z-index:200;
    background:var(--olive-deep);color:#fff;padding:14px 18px;border-radius:0 0 6px 6px;min-height:44px;box-sizing:border-box;display:inline-flex;align-items:center;
    font-family:var(--font-body);font-weight:700;font-size:14px;
    transition:top .2s;
  }
  .skip-link:focus{top:0}

  /* Respect users who ask for less motion */
  @media (prefers-reduced-motion: reduce){
    *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
  }
  body{font-family:var(--font-body);color:var(--brown);background:var(--cream);line-height:1.6;-webkit-font-smoothing:antialiased}

  /* Luxury film-grain texture — subtle tactile paper feel across every section, light or dark */
  .grain{position:fixed;inset:0;z-index:2;pointer-events:none;opacity:.05;mix-blend-mode:overlay;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size:160px 160px}
  @media (prefers-reduced-motion: reduce){.grain{opacity:.035}}

  /* Cursor-tracking gold spotlight — desktop pointer devices only, decorative. Site-wide (not
     hero-scoped, unlike the boosted-dark-mode hero work) — recolored to the same boosted gold
     (#e8ac2e / rgb(232,172,46)) for consistency. The actual --mx/--my values are eased/lagged in
     main.js, not set to the raw cursor position every frame — this rule only cares about the
     custom-property values, not how they're produced.
     2026-07-16 "feels cloudy" fix, round 1: the previous version (520px radius, single fade to
     transparent at 68%, soft-light blend) had no defined core — just one big soft-edged wash, which
     reads as a hazy cloud instead of a glow. Fixed the *shape*: added a genuine solid-ish core
     (0–14%) before the fade starts, and tightened the fade itself (transparent by 52% instead of
     68%) so it reads as a defined pool of light with an edge, not an amorphous cloud. Radius trimmed
     520px→380px to match.
     Round 1 also swapped soft-light→overlay, reasoned (without live verification — browser tooling
     was down) that overlay would have "more contrast in both directions." **That reasoning was wrong,
     caught on live re-check**: worked the blend-mode math by hand for this site's actual colors —
     overlay (and soft-light) both asymptotically approach *no visible change* as the backdrop
     approaches pure white or pure black, because that's how the overlay/soft-light formulas behave at
     the extremes (nothing to do with which one you pick). Concretely: gold at .5 alpha over cream
     (247,242,231) under overlay computes to ≈(249,244,223) — a ~1-8 unit shift, invisible in
     practice. Confirmed live: pinning --mx/--my over the light "Our Brands" cards produced no visible
     glow at all. **Reverted to soft-light** — same math applies to it at extremes, so it's no more or
     less visible than overlay on --cream (an inherent property of contrast-preserving blend modes,
     not a bug to chase further), but soft-light gives a warmer, more grounded look on the DARK
     sections (hero/quote/why/footer) where this effect is actually meant to read, without overlay's
     slightly harsher character there. The shape fix (tight core + 380px radius) is what actually
     solved "cloudy" — kept as-is. Net effect: a visible, defined warm glow on dark sections; a
     near-imperceptible tint on light --cream ones — consistent with the site's restrained aesthetic
     rather than a bug. Verified live this time: glow renders with a defined edge on the hero, no
     console errors, .quote/.why/footer (also dark, untouched by any hero-only work) show it too. */
  .cursor-glow{position:fixed;inset:0;z-index:3;pointer-events:none;mix-blend-mode:soft-light;
    background:radial-gradient(380px circle at var(--mx,50%) var(--my,30%), rgba(232,172,46,.5) 0%, rgba(232,172,46,.42) 14%, transparent 52%)}
  @media (hover:none),(pointer:coarse){.cursor-glow{display:none}}
  @media (prefers-reduced-motion: reduce){.cursor-glow{display:none}}

  /* Scroll progress indicator — thin gold bar tracking page position, sits above the sticky header */
  .scroll-progress{position:fixed;top:0;left:0;height:3px;width:0%;background:var(--gold);z-index:90;transition:width .1s linear;box-shadow:0 0 8px rgba(217,178,94,.6)}

  /* Display serif (Cormorant Garamond) on headlines — warm, classic-menu elegance suited to hospitality, not fashion-editorial severity */
  .hero h1,.sec-head h2,.menu h3,.quote blockquote,.final h2,.scale-num,.trust-stat .num{
    font-family:var(--font-display);
    font-optical-sizing:auto;
  }
  /* padding-inline overrides the shorthand above only where env()/max() are supported; the
     plain `padding:0 28px` stays as the fallback. max() rather than a bare env() because the
     insets are 0 on everything except a notched device held in landscape, and the gutter must
     never shrink below the design's 28px. */
  .wrap{max-width:1180px;margin:0 auto;padding:0 28px;padding-inline:max(28px,env(safe-area-inset-left)) max(28px,env(safe-area-inset-right))}
  a{color:inherit;text-decoration:none}
  .eyebrow{font-family:var(--font-body);text-transform:uppercase;letter-spacing:.22em;font-size:11px;font-weight:700;color:var(--olive-deep)}

  header{position:sticky;top:0;z-index:50;background:rgba(26,20,16,.94);backdrop-filter:blur(12px);border-bottom:1px solid var(--gold-soft);box-shadow:0 8px 30px rgba(0,0,0,.18)}
  /* Desktop nav trimmed 92px→76px + logo/link scale-down, per "header feels too big" — 76px still
     clears the 44px min touch-target guideline with comfortable margin around the logo lockup and
     nav links, just without the extra ~16px of dead vertical padding the old 92px carried. Mobile's
     68px (see the 760px media query below) was already appropriately sized and is untouched. */
  nav{display:flex;align-items:center;justify-content:space-between;height:76px}
  /* ---------- BRAND LOGO — the client's actual Flavours Tec Kitchen mark ----------
     Replaced the typographic wordmark that used to stand in here (the ✦ + "Flavours Tec"
     lockup built from the site's own fonts). Source was a 796x294 PNG on black, recovered from
     FlavoursTec_Kitchen_Investor_Intro.pptx — the only copy on hand with usable resolution; the
     FTK Logo.docx version is a 116x44 crop off a brand sheet and far too small. Black background
     converted to alpha with the ink colours left untouched.
     Served at 260x96 and displayed 44px tall, so it is ~2.2x on a 2x screen. The intrinsic
     width/height attributes are on the <img> to keep it CLS-safe.

     2026-09-11: ftk-logo.png is now the REVERSED (knockout) mark, not the original. The supplied
     logo is brown (93,45,15) and olive (117,129,52) ink drawn for light grounds, and the header
     and footer are both near-black: the olive "Tec"/"KITCHEN" measured 4.30:1 there but
     "Flavours" — the brand name — sat at 1.60:1 and was effectively invisible. The first fix was
     a cream plate behind the logo, which worked but added furniture to the header. This replaces
     it properly: brown lifted to --cream (16.34:1) and the olive kept as olive but lifted in
     value to #b1c168 (9.29:1). Shapes, proportions and spacing are identical to the supplied
     artwork — only the two ink values change, which is what a knockout is.
     Two options were rejected. A single-colour cream version is the textbook knockout but the
     centaur rider and the crescent behind it both go cream, giving 1.00:1 separation inside the
     emblem so it merges into one shape. Recolouring the olive to --gold matched the site better
     but changes the brand's palette rather than only its values.
     Kept on cream deliberately: favicon-*.png and ftk-logo-square.png sit on a light ground, so
     they still use the ORIGINAL dark ink. Do not swap those for the knockout.
     The old wordmark's .site-mark / .site-word / .site-name / .site-sub rules were kept for one
     release so a revert stayed markup-only. The logo swap is settled and live, so they are gone;
     `git log -S .site-mark -- site/styles.css` recovers them if the wordmark is ever wanted back. */
  .site-logo{display:inline-flex;align-items:center;gap:10px;min-height:44px;text-decoration:none;color:inherit;transition:opacity .2s;width:fit-content}
  .site-logo:hover,.site-logo:focus-visible{opacity:.82}
  .site-logo img{height:44px;width:auto;display:block}
  @media(max-width:760px){.site-logo img{height:38px}}
  .navlinks{display:flex;gap:30px;font-family:var(--font-body);font-size:13px;font-weight:500;letter-spacing:.02em;text-transform:uppercase}
  .navlinks a{color:var(--cream);opacity:.75;padding:9px 0;display:inline-block;transition:opacity .2s,color .2s}
  @media(hover:hover){.navlinks a:hover{opacity:1;color:var(--gold)}}
  .navlinks a.active{opacity:1;color:var(--gold);position:relative}
  .navlinks a.active::after{content:'';position:absolute;left:0;right:0;bottom:3px;height:2px;background:var(--gold)}
  .nav-right{display:flex;align-items:center;gap:24px}
  .nav-whatsapp{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;background:#25623a;color:#fff;flex-shrink:0;transition:transform .15s,background .2s}
  .nav-whatsapp:hover,.nav-whatsapp:focus-visible{background:#1d4e2e;transform:translateY(-1px)}
  .nav-whatsapp svg{width:17px;height:17px}
  .nav-toggle{display:none;flex-direction:column;justify-content:center;align-items:center;gap:5px;width:38px;height:38px;background:none;border:none;cursor:pointer;padding:0;flex-shrink:0}
  .nav-toggle-bar{display:block;width:22px;height:2px;background:var(--cream);border-radius:2px;transition:transform .25s ease,opacity .2s ease}
  .nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1){transform:translateY(7px) rotate(45deg)}
  .nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2){opacity:0}
  .nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
  .mobile-menu{display:none;flex-direction:column;padding:6px 0 22px;border-top:1px solid var(--line-light)}
  .mobile-menu a{font-family:var(--font-body);font-size:15px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--cream);opacity:.8;padding:15px 2px;border-bottom:1px solid var(--line-light)}
  .mobile-menu a.active{opacity:1;color:var(--gold)}
  .mobile-menu a.mobile-whatsapp{display:inline-flex;align-items:center;gap:8px;color:#fff;background:#25623a;border-radius:100px;padding:12px 20px;width:fit-content;text-transform:none;font-size:14px;border-bottom:none;margin-top:14px}
  .mobile-menu a.mobile-whatsapp svg{width:17px;height:17px}
  .mobile-menu.open{display:flex}

  /* ---------- BOTTOM TAB BAR — app-style primary nav on mobile, replaces header hamburger ---------- */
  .bottom-tabbar{display:none}
  @media(max-width:760px){
    .bottom-tabbar{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:70;background:rgba(26,20,16,.97);backdrop-filter:blur(14px);border-top:1px solid var(--gold-soft);padding:6px 4px calc(6px + env(safe-area-inset-bottom));justify-content:space-around;box-shadow:0 -8px 24px rgba(0,0,0,.22)}
    /* 12px, not the old 10.5px — these are the only navigation labels below 760px and were under
       the legibility floor. At 12px the tabs stop being equal width at 320px: "Consulting" and
       "WhatsApp" grow their flex items to fit (measured spread 6.6px across the five tabs). The
       old .01em tracking was worth ~0.1px and the 2px side padding was doing nothing for the tap
       target (min-height:48px and flex:1 already cover it), so both are spent on the extra size.
       Measured at 320px: all five tabs land on exactly 62.4px, spread 0. */
    .bottom-tabbar a{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;flex:1;min-height:48px;padding:6px 0;font-family:var(--font-body);font-size:12px;font-weight:600;letter-spacing:0;color:var(--cream);opacity:.6;transition:opacity .2s,color .2s}
    .bottom-tabbar a svg{width:22px;height:22px}
    .bottom-tabbar a.active{opacity:1;color:var(--gold)}
    .bottom-tabbar a.tab-whatsapp{color:#4fae6a;opacity:.95}
    .bottom-tabbar a.tab-whatsapp:hover,.bottom-tabbar a.tab-whatsapp:focus-visible{opacity:1}
  }

  /* ---------- PAGE HEADER BAND (Services/About/Consulting) — reuses hero's ambient dark background, shorter and centered ---------- */
  .page-hero .hero-inner{padding:88px 0 64px}
  .page-hero .hero-copy{max-width:720px}
  .page-hero .hero-emblem{width:min(60vw,460px);height:min(60vw,460px);opacity:.45}
  /* Same desktop vertical-centering fix as .hero (see that rule's comment) — user reported the same
     "gap before content, need to scroll" symptom on the shorter inner-page banners. Uses a smaller
     56vh band (not the homepage's full 100vh) since this content is only eyebrow+h1+p — a full-height
     band here would mostly be empty space and push the real page content further down, which is the
     opposite of what's being fixed. min-height still means taller content isn't clipped.

     2026-09-10: that earlier fix could never have worked, and this is why. .page-hero is a
     <section>, so it took the generic `section{padding:clamp(64px,9vw,120px) 0}` on top of the
     88px/64px it already had on .hero-inner — 208px stacked above the eyebrow, plus the 77px nav,
     for 285px of dead space. Content therefore always exceeded min-height:56vh (484px at a
     1920x865 viewport, against a measured hero of 732px on services, 761px on about, 865px on
     consulting), so the box was never taller than its contents and align-items:center had nothing
     to distribute. The centering was treating the symptom; the double padding was the cause.
     padding-block:0 removes it, and min-height/centering now do what the comment above intended. */
  .page-hero{min-height:56vh;display:flex;align-items:center;padding-block:0}
  @media(max-width:880px){.page-hero{min-height:auto;display:block}}

  /* ---------- HOME SERVICES TEASER — condensed link-cards pointing to the full Services page ---------- */
  .teaser-grid{display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--line);border-radius:6px;overflow:hidden}
  .teaser-card{display:block;padding:28px 24px;border-right:1px solid var(--line);color:inherit;text-decoration:none;transition:background .2s,transform .2s,box-shadow .25s}
  .teaser-card:nth-child(4n){border-right:none}
  @media(hover:hover){.teaser-card:hover{background:var(--cream-dim);transform:translateY(-3px);box-shadow:inset 0 3px 0 0 var(--gold)}}
  .teaser-num{display:block;font-family:var(--font-display);font-weight:600;font-size:26px;color:var(--olive-deep);line-height:1;margin-bottom:10px}
  .teaser-card h3{font-family:var(--font-display);font-weight:600;font-size:17px;letter-spacing:-.005em;color:var(--brown);line-height:1.25;margin-bottom:8px}
  .teaser-card .teaser-link{font-family:var(--font-body);font-size:12px;font-weight:700;letter-spacing:.04em;color:var(--olive-deep)}
  .teaser-more{text-align:center;margin-top:36px}
  @media(max-width:820px){.teaser-grid{grid-template-columns:1fr 1fr}.teaser-card:nth-child(2n){border-right:none}.teaser-card:nth-child(-n+2){border-bottom:1px solid var(--line)}}
  @media(max-width:760px){.teaser-grid{display:flex;overflow-x:auto;-webkit-overflow-scrolling:touch;scroll-snap-type:x mandatory;border:none;border-radius:0;gap:12px;margin:0 -28px;padding:2px 28px 8px;scrollbar-width:none}.teaser-grid::-webkit-scrollbar{display:none}.teaser-card{flex:0 0 76%;max-width:280px;border:1px solid var(--line)!important;border-radius:10px!important;background:#fff;scroll-snap-align:start}}
  /* `border:1px solid transparent`, not `border:none`: .btn-ghost declares a real 1px border
     and the others did not, so a ghost button sat 2px taller than an olive one beside it. With
     one solid and two ghost buttons in the hero row that misalignment became visible. Reserving
     the border on the base keeps every button the same box; each variant only recolours it. */
  .btn{font-family:var(--font-body);font-weight:700;font-size:14px;letter-spacing:.015em;padding:12px 26px;border-radius:100px;display:inline-block;cursor:pointer;border:1px solid transparent;transition:transform .18s,background .2s,box-shadow .25s}
  .btn-olive{background:var(--olive-deep);color:#fff;box-shadow:0 8px 20px rgba(125,90,30,.28)}
  @media(hover:hover){.btn-olive:hover{background:var(--olive-deeper);transform:translateY(-2px);box-shadow:0 14px 30px rgba(125,90,30,.38)}}
  .btn-ghost{background:transparent;color:var(--cream);border:1px solid rgba(247,242,231,.42)}
  @media(hover:hover){.btn-ghost:hover{background:rgba(247,242,231,.12);transform:translateY(-2px)}}
  .btn-brown{background:var(--brown);color:var(--cream);box-shadow:0 8px 20px rgba(26,20,16,.28)}
  @media(hover:hover){.btn-brown:hover{background:var(--brown-soft);transform:translateY(-2px);box-shadow:0 14px 30px rgba(26,20,16,.32)}}
  @media(max-width:760px){.navlinks{display:none}.nav-right{display:none}nav{height:68px;justify-content:center}}

  /* Hero-only "boosted dark mode" palette (2026-07-16, from the black/orange palette review) — the
     highlight accent (headline highlight word, emblem, gradient-bars) is pushed to a punchier gold,
     #e8ac2e — same hue family (~40°) as --gold/--olive, not the orange the review rejected for being
     off-positioning. Scoped to .hero/.page-hero only: --brown/--gold/--olive tokens themselves are
     untouched, so every other section (why, quote, footer, buttons) is unaffected. The eyebrow and
     .chip borders were deliberately left at the original muted --olive/--gold so the boosted gold
     reads as a hierarchy accent, not a blanket recolor — revisit if a fuller boost is wanted.
     2026-07-16 "keep it stark black" revision: background was a warm near-black linear gradient
     (#0c0906–#2c2110) through several iterations (see PROJECT-NOTES work log for the mobile-visibility
     and "clean and visible" fixes that shaped it) — user asked directly to make the hero flat stark
     black instead, so it's now a plain #0a0a0a, no gradient. The gold accents (highlight word, emblem,
     bars, glow) are unchanged and still carry all the warmth/richness — only the base tone reverted
     from "warm near-black" to true neutral black. This does NOT reintroduce the earlier-rejected
     stark-black-and-ORANGE direction — the accent is still gold, not orange; only "stark black" (the
     ground, not the hue of the accent) was the ask this time. */
  .hero{background:#0a0a0a;color:var(--cream);position:relative;overflow:hidden}
  /* Desktop: fill the space below the sticky 77px header (76px nav + 1px border) and vertically
     center the hero copy, so the full hero (headline through CTA) reads as "framed" on load instead
     of starting mid-content and needing a scroll to reach the center — .page-hero (the shorter
     Services/About/Consulting banner) shares the .hero class but is deliberately excluded, it was
     never meant to be full-height. min-height (not height) means content taller than the viewport
     still grows the box normally instead of being clipped by .hero's overflow:hidden. Reverted to
     normal flow on mobile below. */
  /* padding-block:0 cancels the generic `section{padding:clamp(64px,9vw,120px) 0}` further down.
     The hero already carries its own vertical padding on .hero-inner (108px/64px), so it was
     getting both: 120px + 108px = 228px stacked above the eyebrow, plus the 77px nav, for 305px of
     dead space before the first word. That made the hero 1084px tall at every laptop width —
     measured identical at 1280, 1366, 1440, 1536, 1600 and 1920 — against a typical laptop viewport
     of 600-950px, so the scale widget (and the CTAs on shorter screens) fell below the fold. Only
     ~609px of that 1084px was content; 475px was padding.
     Specificity, not source order, is what makes this win: `.hero:not(.page-hero)` is (0,2,0) and
     `section` is (0,0,1), so it holds even though the section rule appears ~100 lines later.
     Side effect worth knowing: min-height now actually binds on tall viewports, so the
     align-items:center above finally does something instead of being dead weight. */
  .hero:not(.page-hero){min-height:calc(100vh - 77px);display:flex;align-items:center;padding-block:0}
  /* animated gradient-bars background — replaced the photo hero-bg (see PROJECT-NOTES work log for
     the full photo history: real event photo on index.html, per-page Pexels stock on
     services/about/consulting) with a ported version of a React "GradientBars" component the user
     supplied. Same z-index:0 layer the photo used to occupy, same .hero::before scrim on top
     unmodified. numBars=15 divs, each a bottom-anchored linear-gradient (gold → transparent) whose
     height follows the source component's curve: SHORT (30%) in the center, tall (100%) at the
     edges — i.e. a valley shape, not a typical equalizer — which conveniently keeps the bars mostly
     clear of the centered hero copy. Heights/animation are computed in main.js's initGradientBars().
     Color uses rgba(232,172,46,.55) — the boosted hero gold at 55% alpha, not fully opaque —
     specifically because a fully-opaque bar peak behind the scrim would blow past a safe margin. At
     .55 alpha the worst-case composite (bar-over-#0a0a0a-base, then the now-neutral-black .55 scrim
     wash over that) computes to ~6.38:1 for the eyebrow (boosted to #e8ac2e, see the .hero::before
     comment below) — a real improvement over the ~4.96:1 this had with the old brown-tinted wash over
     a warm-black gradient base, since a neutral-black-on-neutral-black composite is darker than
     brown-on-brown was. Still comfortably above the 4.5:1 AA-small floor. Don't raise the bar alpha
     without redoing this math if it's ever pushed further than this. */
  .gradient-bars{position:absolute;inset:0;width:100%;height:100%;z-index:0;overflow:hidden;pointer-events:none;display:flex}
  .gradient-bars .bar{flex:1;height:100%;background:linear-gradient(to top, rgba(232,172,46,.55), transparent);transform-origin:bottom;transition:transform .5s ease-in-out;animation:pulseBar var(--bar-duration,2s) ease-in-out infinite alternate;box-sizing:border-box}
  @keyframes pulseBar{0%{transform:scaleY(var(--initial-scale,1))}100%{transform:scaleY(calc(var(--initial-scale,1) * 0.7))}}
  @media(prefers-reduced-motion:reduce){.gradient-bars .bar{animation:none}}
  /* .page-hero matches .hero's stark black (2026-07-16) — previously its own richer diagonal
     warm-black gradient, flattened to the same #0a0a0a for consistency now that .hero is flat too. */
  .page-hero{background:#0a0a0a}
  /* text-legibility scrim over .gradient-bars, on every page.
     2026-07-16: the static top-center gold glow (linear 180deg wash + radial "90% 70% at 50% 0%")
     that used to sit here was removed — user called it "the fog like thing on top of page view,"
     and it's an apt description: unlike the cursor-glow (which moves and fades away), this was a
     fixed warm haze parked at the top of every .hero/.page-hero regardless of interaction, visible
     in literally every screenshot taken this session. Kept: the flat wash (still needed for text
     contrast) and the bottom black vignette (pure darkening, not a warm glow, doesn't read as fog).
     Wash alpha (.55, dropped from .75 in an earlier pass) and color (neutral rgba(0,0,0,*), matching
     the flat #0a0a0a base) are unchanged from before — see PROJECT-NOTES for that history. Removing
     the gold glow layers only *helps* contrast (one less brightening layer over the text), so the
     eyebrow's ~6.38:1 worst-case margin logged previously still holds as a floor, not a ceiling. */
  .hero::before{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;background:
     radial-gradient(80% 60% at 50% 100%, rgba(0,0,0,.34), transparent 60%),
     rgba(0,0,0,.55)}
  /* The hero's vertical rhythm answers to viewport HEIGHT, not just width, because height is the
     scarce axis on a laptop. A 1920x1080 panel at 150% display scaling gives a ~1280x582 logical
     viewport, and at that height the fixed 108px/64px left the CTAs 84px below the fold even after
     the double-padding fix. 8vh/6vh shrink the band exactly where height is short and cap at the
     original 108px/64px, so nothing changes on a tall screen: at 582px high this yields 47px/35px,
     at 865px it is 69px/52px, and from ~1350px up it is the original values.
     The `padding:108px 0 64px` shorthand stays as the fallback and to zero the inline padding;
     padding-block then overrides the block axis, the same shorthand-plus-logical pattern .wrap uses.
     Deliberately not applied below 880px: the media query further down re-sets this with the
     shorthand, so mobile keeps its separately tuned 72px/64px and is untouched by this rule. */
  .hero-inner{position:relative;z-index:2;padding:108px 0 64px;padding-block:clamp(32px,8vh,108px) clamp(24px,6vh,64px);width:100%}
  /* abstract compass-rose emblem standing in for photography — an honest decorative crest
     (obviously stylised linework, not a fabricated photo of a real event), echoing the ✦ mark
     used in the logo. Sits behind .hero-copy via explicit stacking, not implicit DOM order. */
  .hero-emblem{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:min(78vw,640px);height:min(78vw,640px);color:#e8ac2e;opacity:.55;z-index:0;pointer-events:none}
  .hero-copy{position:relative;z-index:1;max-width:760px;margin:0 auto;text-align:center}
  @media(max-width:640px){.hero-emblem{width:min(100vw,460px);height:min(100vw,460px);opacity:.4}}
  .hero .pill{display:inline-flex;align-items:center;gap:8px;font-family:var(--font-body);font-size:12.5px;letter-spacing:.04em;background:rgba(247,242,231,.1);border:1px solid var(--gold-soft);padding:7px 14px;border-radius:100px;margin-bottom:20px}
  .hero .pill .dot{width:7px;height:7px;border-radius:50%;background:var(--gold);box-shadow:0 0 0 3px rgba(217,178,94,.25)}
  .hero .eyebrow{color:#e8ac2e;display:block;margin-bottom:16px}
  /* min(5.6vw,11vh) adds a height term to the same idea: the headline is three lines at every
     laptop width, so on a short viewport it is the single biggest consumer of vertical space and
     trimming padding alone could not clear the fold. 11vh only wins where height is genuinely
     scarce — at 1280x582 it gives 64px against 5.6vw's 71.7px, which is what puts the CTAs above
     the fold; at 1920x865 and taller the vw term and the 78px cap both win, so wide screens are
     unchanged; and mobile stays pinned to the 40px floor. */
  /* text-wrap:balance because this headline is long enough to strand its last word. Measured on a
     1280x590 viewport (a 1920x1080 laptop at 150% display scaling, which is the common Windows
     default) the three lines came out 747 / 656 / 192px in a 760px column — "presence." alone on
     line three. Balanced they are 526 / 534 / 535.
     9.5vh rather than 11vh in the height term: on a tall screen the 5.6vw term wins and nothing
     changes (1440x900 and 1920x1080 both still cap at 78px), but on a short one the headline was
     staying big enough to need that third line and to crowd the CTA down to 51px of clearance.
     At 9.5vh the same viewport sets 56px, fits two lines, and the CTA gets 138px. */
  .hero h1{font-weight:600;font-size:clamp(40px,min(5.6vw,9.5vh),78px);line-height:1.05;letter-spacing:-.02em;margin:0 0 22px;text-wrap:balance}
  .hero h1 .olive{color:#e8ac2e;font-style:italic}
  .hero p{font-size:18px;max-width:620px;margin:0 auto 34px;opacity:.85;line-height:1.6}
  .hero-cta{display:flex;gap:13px;flex-wrap:wrap;align-items:center;justify-content:center}
  .hero-cta .btn{padding:14px 26px}
  /* Once the row wraps, the buttons stack — and a stack of pills sized by their own label text
     tapers, which reads as broken rather than centred. Measured on a 430x932 iPhone Pro Max the
     three widths were 228 / 196 / 226, a 32px spread down the stack. Below 760px they share one
     width instead. Capped at 340px so they stay pill-shaped rather than stretching the full
     374px of a Pro Max content column, and centred so the cap does not shift them left. */
  @media(max-width:760px){
    .hero-cta{flex-direction:column;align-items:center}
    .hero-cta .btn{width:100%;max-width:340px;text-align:center}
  }
  /* The response-time promise, directly under the CTAs: it answers "how long until I hear
     back?" at the moment the question is felt, rather than in small type near the footer.
     Scoped `.hero .hero-reply` deliberately: a bare `.hero-reply` (0,1,0) loses to the
     `.hero p` rule above (0,1,1), which would hold it at 18px with no top margin. */
  .hero .hero-reply{margin-top:14px;font-size:14px;line-height:1.6;opacity:.72;max-width:46ch}
  /* Short phones — 667px tall and below, i.e. iPhone SE / 8 and the Androids that match them.
     The .bottom-tabbar is position:fixed over the bottom ~68px of the viewport below 760px, so the
     usable height on a 375x667 device is 667 - 77 (header) - 68 (bar) = 522px. The hero's content
     is taller than that no matter what, so the fix is not to make it fit but to get the primary
     CTA above the bar: measured there, the WhatsApp button ran 617-669 against a bar starting at
     599, i.e. entirely hidden on first paint.
     Tightening type and margins above the CTA buys the 115px that takes. Tap targets and the
     buttons themselves are deliberately untouched — shrinking those to win vertical space trades
     one accessibility problem for another.
     Note this hero is display:block below 880px (see the rule further down), not the centred flex
     box it is on desktop, so there is nothing to be gained here from min-height or align-items. */
  @media(max-width:760px) and (max-height:720px){
    .hero h1{font-size:clamp(32px,min(5.6vw,11vh),78px);margin:0 0 14px}
    .hero p{font-size:16px;margin:0 auto 20px}
    .hero .hero-reply{margin-top:10px}
    .hero-inner{padding:48px 0 40px}
    .scale{margin-top:26px;padding-top:16px}
  }
  /* animated guest-scale strip, centered under the CTA */
  .scale{margin:44px auto 0;max-width:460px;border-top:1px solid var(--line-light);padding-top:22px}
  .scale-row{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;font-family:var(--font-body)}
  .scale-num{font-size:clamp(36px,5vw,52px);font-weight:600;letter-spacing:-.02em;color:var(--olive);line-height:1}
  .scale-label{font-size:12.5px;text-transform:uppercase;letter-spacing:.16em;opacity:.7;max-width:150px;text-align:right;line-height:1.4;padding-top:6px}
  .scale-track{height:5px;background:var(--line-light);border-radius:4px;margin-top:14px;overflow:hidden}
  .scale-fill{height:100%;width:8%;background:var(--olive);border-radius:4px}
  .scale-ticks{display:flex;justify-content:space-between;font-family:var(--font-body);font-size:11px;opacity:.55;margin-top:8px;letter-spacing:.1em}
  @media(max-width:880px){
    .hero-inner{padding:72px 0 64px}
    .hero:not(.page-hero){min-height:auto;display:block}
  }

  .trust{background:var(--cream-dim);color:var(--brown);padding:32px 0;border-top:3px solid var(--olive-deep);box-shadow:0 12px 30px rgba(26,20,16,.1)}
  .trust-stats{display:flex;align-items:stretch;justify-content:center;flex-wrap:wrap;gap:0}
  .trust-stat{text-align:center;padding:4px 34px;border-right:1px solid var(--line)}
  .trust-stat:last-child{border-right:none}
  .trust-stat .num{font-weight:600;font-size:30px;letter-spacing:-.02em;color:var(--olive-deep);line-height:1.1}
  .brand-dots{display:flex;justify-content:center;gap:5px;margin-top:9px}
  .brand-dots span{width:7px;height:7px;border-radius:50%;display:inline-block;box-shadow:0 0 0 1px rgba(26,20,16,.08)}
  .trust-stat .lbl{font-family:var(--font-body);font-size:12px;letter-spacing:.08em;text-transform:uppercase;opacity:.62;margin-top:4px}
  .trust-certs{display:flex;align-items:center;justify-content:center;gap:14px;flex-wrap:wrap;margin-top:20px;padding-top:18px;border-top:1px solid var(--line)}
  .trust-certs .label{font-family:var(--font-body);font-size:11px;letter-spacing:.16em;text-transform:uppercase;opacity:.65}
  .cert{font-family:var(--font-body);font-size:12px;font-weight:700;letter-spacing:.04em;color:var(--olive-deep);border:1px solid var(--line);border-radius:4px;padding:6px 12px;opacity:.9}
  @media(max-width:760px){.trust-stat{padding:8px 20px;border-right:none}.trust-stat .num{font-size:26px}}

  /* ---------- VENUE-TYPE PILLS — wraps on desktop, swipeable "kinetic marquee" on mobile only ---------- */
  /* Desktop default: wrap + center (the hero's old .chip-row pill list used the same wrap pattern
     before it was removed 2026-07-17 to shorten the hero). Previously this row scrolled at ALL sizes
     with the scrollbar hidden (scrollbar-width:none), so on desktop — no touch gesture, no visible
     scrollbar — the 6th pill ("Exhibition Grounds") was permanently invisible with no cue it existed.
     Reverts to the original horizontal swipe below 760px (see media query), where swipe is a
     discoverable, expected gesture — matching the same breakpoint .teaser-grid/.menu-grid/.partner-grid
     already use for this exact desktop-wraps/mobile-swipes pattern. */
  .venue-scroll{background:var(--brown-soft);border-top:1px solid var(--gold-soft);border-bottom:1px solid var(--gold-soft);padding:14px 0}
  .venue-scroll-track{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;max-width:1180px;margin:0 auto;padding:0 28px;padding-inline:max(28px,env(safe-area-inset-left)) max(28px,env(safe-area-inset-right))}
  .venue-pill{display:inline-flex;align-items:center;font-family:var(--font-body);font-size:12.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:rgba(247,242,231,.82);white-space:nowrap;border:1px solid var(--gold-soft);border-radius:100px;padding:9px 17px;transition:background .2s,border-color .2s}
  .venue-pill:hover,.venue-pill:focus-visible{background:rgba(217,178,94,.14);border-color:var(--gold)}
  @media(max-width:760px){
    .venue-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
    .venue-scroll::-webkit-scrollbar{display:none}
    .venue-scroll-track{flex-wrap:nowrap;justify-content:flex-start;width:max-content;max-width:none;margin:0;padding:0 20px;scroll-snap-type:x proximity}
    .venue-pill{scroll-snap-align:start}
  }

  section{padding:clamp(64px,9vw,120px) 0}
  .sec-head{max-width:680px;margin-bottom:52px}
  .sec-head h2{font-weight:600;font-size:clamp(30px,4.5vw,46px);letter-spacing:-.015em;line-height:1.05;margin:14px 0 16px}
  .sec-head p{font-size:18px;opacity:.78;max-width:560px}

  /* ---------- FOUR-PILLAR CAPABILITIES — scannable 2x2 grid, not a long vertical read ---------- */
  .pillars{display:grid;grid-template-columns:1fr 1fr;border:1px solid var(--line);border-radius:6px;overflow:hidden}
  .pillar{padding:34px 32px;border-right:1px solid var(--line);border-bottom:1px solid var(--line);transition:background .2s,transform .2s,box-shadow .25s;scroll-margin-top:80px}
  .pillar:nth-child(2n){border-right:none}
  .pillar:nth-child(n+3){border-bottom:none}
  @media(hover:hover){.pillar:hover{background:var(--cream-dim);transform:translateY(-3px);box-shadow:inset 0 3px 0 0 var(--gold)}}
  .pillar-num{display:block;font-family:var(--font-display);font-weight:600;font-size:32px;color:var(--olive-deep);line-height:1;margin-bottom:12px}
  .pillar-body h3{font-family:var(--font-display);font-weight:600;font-size:clamp(19px,2vw,22px);letter-spacing:-.01em;margin-bottom:9px;color:var(--brown);line-height:1.2}
  .pillar-body p{font-size:14.5px;line-height:1.55;opacity:.76;margin-bottom:16px}
  .pillar-tags{display:flex;flex-wrap:wrap;gap:8px;list-style:none}
  /* 12px, not 10.5px — these chips ("Delegate catering", "Live counters", "VIP hospitality") are
     the substantive content of each service pillar, not decoration. No compensating tweak needed:
     measured at 320px, nothing overflows and the tallest pillar grows 442px -> 449px. */
  .pillar-tags li{font-family:var(--font-body);font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--olive-deep);border:1px solid var(--line);border-radius:100px;padding:5px 12px}
  @media(max-width:820px){.pillars{grid-template-columns:1fr}.pillar{border-right:none!important}.pillar:nth-child(n+3){border-bottom:1px solid var(--line)}.pillar:last-child{border-bottom:none}}

  .also-available{margin-top:8px;padding-top:30px;border-top:1px solid var(--gold-soft);display:flex;flex-wrap:wrap;align-items:center;gap:16px}
  .also-available .label{font-family:var(--font-body);font-size:11px;letter-spacing:.16em;text-transform:uppercase;opacity:.68}
  .also-available a{font-family:var(--font-body);font-size:13px;font-weight:600;color:var(--brown);border-bottom:1px solid var(--line);padding:6px 0 4px;display:inline-block}
  /* Touch targets. .also-available a renders 32px tall and .menu a 27px — both clear WCAG 2.5.8
     AA (24px) but fail the 44px touch guideline, and both are underlined links, so growing them
     with padding would drop the underline away from the text and change the design. An invisible
     ::after centred on each link expands only the hit area: nothing moves, nothing repaints.
     Coarse pointers only — mouse users already pass at AA, so desktop stays provably untouched.
     Measured at 375px: 32px -> 45px and 27px -> 45px effective, with zero overlapping hit zones
     (the .also-available rows sit on a 47-48px pitch, so the 12px of expansion leaves 4px). */
  @media (pointer: coarse){
    .also-available a,.menu a{position:relative}
    .also-available a::after,.menu a::after{content:"";position:absolute;left:0;right:0;top:50%;height:44px;transform:translateY(-50%)}
  }
  .also-available a:hover,.also-available a:focus-visible{color:var(--olive-deep);border-color:var(--olive-deep)}

  .why{background:var(--brown);color:var(--cream)}
  .why .sec-head h2{max-width:560px}
  .why .eyebrow{color:var(--olive)}
  .why-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px 56px;margin-top:10px}
  .why-item{display:flex;gap:16px;padding:22px 0;border-top:1px solid var(--line-light)}
  .why-item .chk{color:var(--olive);font-family:var(--font-body);font-weight:800;font-size:20px;flex-shrink:0}
  .why-item h3{font-family:var(--font-body);font-size:17px;margin-bottom:5px}
  .why-item p{font-size:15px;opacity:.72}
  @media(max-width:760px){.why-grid{grid-template-columns:1fr;gap:0}}

  /* ---------- OUR BRANDS — a named, tagged roster of specialist kitchens, not a plain logo wall ---------- */
  .brands{background:var(--cream)}
  .brand-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
  .brand{background:#fff;border:1px solid var(--line);border-radius:10px;padding:24px 20px;display:flex;flex-direction:column;align-items:center;text-align:center;transition:transform .2s,box-shadow .2s,border-color .2s;box-shadow:0 2px 10px rgba(26,20,16,.06)}
  @media(hover:hover){.brand:hover{transform:translateY(-4px);box-shadow:0 18px 36px rgba(26,20,16,.12);border-color:var(--gold-soft)}}
  .brand-logo{display:inline-flex;align-items:center;justify-content:center;height:64px;padding:0 28px;border-radius:100px;background:#fff;border:1px solid var(--line);margin-bottom:16px;transition:background .2s,border-color .2s,box-shadow .2s;box-shadow:0 1px 3px rgba(26,20,16,.06)}
  @media(hover:hover){.brand:hover .brand-logo{border-color:var(--gold-soft);background:var(--cream-dim)}}
  .brand-logo img{max-height:46px;max-width:160px;width:auto;height:auto;object-fit:contain;display:block}
  /* text-only "logo" for brands with no supplied logo asset (e.g. BSquare Hospitality) — sits in the
     same pill as the image logos, just a styled wordmark instead of a <picture>. */
  .brand-wordmark{font-family:var(--font-display);font-style:italic;font-weight:600;font-size:15px;line-height:1.2;letter-spacing:-.005em;color:var(--brown);white-space:nowrap}
  .brand-swatch{width:26px;height:3px;border-radius:3px;margin:0 auto 14px}
  .brand-name{font-family:var(--font-display);font-weight:600;font-size:17px;letter-spacing:-.005em;color:var(--brown)}
  /* 12px, and tracking trimmed .1em -> .06em to pay for it. At 12px with the original .1em, two of
     the five tags wrap to a second line at 320px (measured heights 19,19,19,38,38), which leaves the
     brand cards visibly uneven. At .06em all five sit on one line at 19px. */
  .brand-tag{font-family:var(--font-body);font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--olive-deep);margin-top:7px}
  @media(max-width:820px){.brand-grid{grid-template-columns:repeat(2,1fr)}}
  @media(max-width:480px){.brand-grid{grid-template-columns:1fr}}

  /* ---------- OUR ESTEEMED CLIENTS / FOOD COURT PARTNERS — dense trust-signal logo walls ---------- */
  .partners{background:var(--cream-dim)}
  .partners + .partners{background:var(--cream)}
  .partner-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:14px}
  .partner-logo{display:flex;align-items:center;justify-content:center;height:88px;padding:12px 16px;border-radius:8px;background:#fff;border:1px solid var(--line);transition:transform .2s,box-shadow .2s,border-color .2s;box-shadow:0 2px 8px rgba(26,20,16,.05)}
  @media(hover:hover){.partner-logo:hover{transform:translateY(-3px);box-shadow:0 14px 28px rgba(26,20,16,.1);border-color:var(--gold-soft)}}
  .partner-logo img{width:auto;height:auto;max-width:100%;object-fit:contain;display:block}
  @media(max-width:980px){.partner-grid{grid-template-columns:repeat(4,1fr)}}
  @media(max-width:760px){.partner-grid{display:grid;grid-auto-flow:column;grid-template-rows:repeat(2,1fr);grid-template-columns:none;grid-auto-columns:108px;gap:10px;overflow-x:auto;-webkit-overflow-scrolling:touch;scroll-snap-type:x proximity;margin:0 -28px;padding:2px 28px 8px;scrollbar-width:none}.partner-grid::-webkit-scrollbar{display:none}.partner-logo{scroll-snap-align:start;height:80px}}

  /* ---------- OUR MISSION callout inside Why section ---------- */
  .mission-note{margin-top:36px;padding:24px 28px;border-left:3px solid var(--gold);background:rgba(247,242,231,.05)}
  .mission-label{font-family:var(--font-body);font-size:11px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--gold);display:block;margin-bottom:10px}
  .mission-note p{font-family:var(--font-body);font-size:15.5px;line-height:1.7;opacity:.88;max-width:760px}
  .mission-note p a{color:var(--gold);text-decoration:underline;text-underline-offset:3px;opacity:1}
  .mission-note p a:hover,.mission-note p a:focus-visible{color:var(--cream)}

  /* ---------- FAQ ACCORDION — collapsed by default, click to expand ---------- */
  .faq{background:var(--cream-dim)}
  .faq-list{max-width:780px;margin:0 auto}
  .faq-item{border-top:1px solid var(--line)}
  .faq-item:last-child{border-bottom:1px solid var(--line)}
  .faq-q{display:flex;align-items:center;justify-content:space-between;gap:20px;width:100%;text-align:left;background:none;border:none;cursor:pointer;padding:22px 4px;font-family:var(--font-display);font-weight:600;font-size:20px;letter-spacing:-.01em;line-height:1.3;color:var(--brown);transition:color .2s}
  @media(hover:hover){.faq-q:hover{color:var(--olive-deep)}}
  .faq-chevron{width:20px;height:20px;flex-shrink:0;color:var(--olive-deep);transition:transform .25s ease}
  .faq-item.open .faq-chevron{transform:rotate(180deg)}
  .faq-a{display:grid;grid-template-rows:0fr;transition:grid-template-rows .3s ease}
  .faq-a > div{overflow:hidden}
  .faq-a p{font-size:16px;opacity:.82;max-width:680px;padding:0 4px 24px}
  .faq-item.open .faq-a{grid-template-rows:1fr}

  .menus{background:var(--cream-dim)}.menu-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
  .menu{background:var(--cream);border:1px solid var(--line);border-radius:4px;padding:30px 24px;display:flex;flex-direction:column;transition:transform .2s,box-shadow .2s}
  @media(hover:hover){.menu:hover{transform:translateY(-4px);box-shadow:0 18px 40px rgba(26,20,16,.12)}}
  /* 12px — these state what each package is for ("100+ guests", "Live counters"), which is
     buyer-facing. No tracking change needed: measured at 320px nothing wraps and the menu card
     grows 438px -> 439px. */
  .menu .tag{font-family:var(--font-body);font-size:12px;text-transform:uppercase;letter-spacing:.16em;color:var(--olive-deep);font-weight:700}
  .menu h3{font-size:24px;font-weight:600;margin:12px 0 6px;letter-spacing:-.005em}
  .menu .price{font-family:var(--font-body);font-weight:800;font-size:15px;color:var(--olive-deep);margin-bottom:16px}
  .menu p{font-size:15px;opacity:.78;flex:1}
  .menu a{margin-top:20px;font-family:var(--font-body);font-weight:700;font-size:14px;color:var(--brown);border-bottom:2px solid var(--olive);padding-bottom:3px;align-self:flex-start}
  @media(max-width:980px){.menu-grid{grid-template-columns:1fr 1fr}}
  @media(max-width:760px){.menu-grid{display:flex;overflow-x:auto;-webkit-overflow-scrolling:touch;scroll-snap-type:x mandatory;gap:14px;margin:0 -28px;padding:2px 28px 8px;scrollbar-width:none}.menu-grid::-webkit-scrollbar{display:none}.menu{flex:0 0 78%;max-width:290px;scroll-snap-align:start}}

  .steps{display:grid;grid-template-columns:repeat(3,1fr);gap:0}
  .step{padding:0 34px;border-left:1px solid var(--line)}
  .step:first-child{padding-left:0;border-left:none}
  .step .n{font-family:var(--font-body);font-weight:800;font-size:54px;color:var(--olive-deep);letter-spacing:-.04em;line-height:1}
  .step h3{font-family:var(--font-body);font-size:20px;margin:14px 0 8px}
  .step p{font-size:15px;opacity:.78}
  @media(max-width:760px){.steps{grid-template-columns:1fr;gap:32px}.step{padding-left:0;border-left:none}}

  /* ---------- "FROM OUR EVENTS" PHOTO SHOWCASE — real event photography, image+copy pair (services.html) ---------- */
  .showcase-grid{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:center}
  .showcase-media{border-radius:8px;overflow:hidden;box-shadow:0 24px 60px rgba(26,20,16,.18)}
  .showcase-media img{display:block;width:100%;height:auto}
  .showcase-copy h2{font-family:var(--font-display);font-weight:600;font-size:clamp(28px,3.6vw,42px);letter-spacing:-.015em;line-height:1.1;margin:14px 0 16px;color:var(--brown)}
  .showcase-copy p{font-size:17px;line-height:1.65;opacity:.8;margin-bottom:26px;max-width:440px}
  @media(max-width:820px){.showcase-grid{grid-template-columns:1fr;gap:28px}.showcase-media{order:-1}.showcase-copy p{max-width:none}}

  .quote{position:relative;background:var(--brown);color:var(--cream);text-align:center;border-top:1px solid var(--gold-soft);border-bottom:1px solid var(--gold-soft);overflow:hidden}
  .quote::before{content:'\201C';position:absolute;top:-.12em;left:50%;transform:translateX(-50%);font-family:var(--font-display);font-size:260px;line-height:1;color:var(--gold);opacity:.14;pointer-events:none;z-index:0}
  .quote .wrap{position:relative;z-index:1}
  .quote .eyebrow{color:rgba(247,242,231,.78);display:block;margin-bottom:18px}
  .quote blockquote{font-size:clamp(24px,3.6vw,38px);line-height:1.3;max-width:840px;margin:0 auto;letter-spacing:-.01em}
  .quote blockquote .hl{color:var(--gold)}
  .quote cite{display:block;margin-top:28px;font-family:var(--font-body);font-style:normal;font-size:14px;letter-spacing:.06em;opacity:.85}

  .final{background:var(--olive-deep);color:#fff;text-align:center}
  .final h2{font-weight:600;font-size:clamp(32px,5vw,56px);letter-spacing:-.02em;line-height:1.02;margin-bottom:16px}
  .final p{font-size:18px;margin-bottom:30px;opacity:.92}

  /* ---------- ENQUIRY FORM (enquire.html) ----------
     Layout, control sizing and field-visibility notes in PROJECT-NOTES.md >
     "Shipped-file rationale" > styles.css. */
  .enquiry-form{display:grid;grid-template-columns:1fr 1fr;gap:20px 28px;max-width:760px;margin:0 auto}
  .enquiry-form .field-wide{grid-column:1 / -1}
  .enquiry-form label{display:block;font-family:var(--font-body);font-size:13px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--olive-deep);margin-bottom:7px}
  .enquiry-form input,.enquiry-form select,.enquiry-form textarea{width:100%;min-height:48px;font-family:var(--font-body);font-size:16px;color:var(--brown);background:#fff;border:1px solid var(--line);border-radius:6px;padding:12px 14px}
  .enquiry-form textarea{min-height:120px;resize:vertical}
  .enquiry-form input:focus-visible,.enquiry-form select:focus-visible,.enquiry-form textarea:focus-visible{border-color:var(--olive-deep)}
  .form-note{font-family:var(--font-body);font-size:13px;opacity:.7;margin-top:10px}
  .hp-field{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
  @media(max-width:760px){.enquiry-form{grid-template-columns:1fr;gap:18px}}

  /* ---------- FOOTER — disciplined grid so columns align predictably at every width ---------- */
  footer{background:var(--brown-soft);color:var(--cream);padding:60px 0 32px}
  @media(max-width:760px){footer{padding-bottom:calc(32px + 70px + env(safe-area-inset-bottom))}}
  .foot{display:grid;grid-template-columns:1.3fr 1fr 1fr 1fr;gap:40px;border-bottom:1px solid var(--line-light);padding-bottom:36px}
  .foot-brand{max-width:280px}
  .footer-logo{margin-bottom:16px}
  .foot-tagline{font-family:var(--font-body);font-size:14px;line-height:1.6;opacity:.7}
  /* Was `.foot .col h5`. These label link groups rather than opening sections, so they are
     no longer headings — which also ends the h2 -> h5 level skip on every page. font-weight
     is declared here for the first time: h5 was bold by user-agent default and this rule
     never said so, while <p> defaults to 400. Without it the labels silently go light. */
  .foot .col .col-label{font-family:var(--font-body);font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.16em;opacity:.55;margin-bottom:16px;padding-bottom:10px;border-bottom:1px solid var(--line-light)}
  /* The Services and Company columns are <nav> landmarks now, so they pick up the bare
     `nav{display:flex;height:76px}` type selector at :101 — written for the header nav, but it
     matches every <nav> on the page. Unopted-out, the two columns collapse into 76px-tall flex
     rows and their links run horizontally. Restores what `<div class="col">` rendered as.
     Scoped to `.foot nav.col` so the header nav and .bottom-tabbar are untouched. */
  .foot nav.col{display:block;height:auto}
  .foot .col a{display:flex;align-items:center;gap:8px;font-family:var(--font-body);font-size:14px;opacity:.8;padding:11px 0;margin-bottom:0;min-height:44px;transition:opacity .2s,color .2s}
  .foot .col a:hover,.foot .col a:focus-visible{opacity:1;color:var(--gold)}
  /* The footer-link rule above is (0,2,1) and so beats .site-logo (0,1,0), catching the footer
     brand lockup as well as the nav links. That mattered while the logo sat on a cream plate:
     it stretched the plate across the whole 280px column and replaced its padding. The plate is
     gone now that the logo is a knockout, so the padding it forces is invisible again and the
     override that corrected it has been removed — the lockup takes the same 11px/0 it did before
     the plate existed. `width:fit-content` moved onto .site-logo itself so the anchor still hugs
     the mark rather than spanning the column; this rule sets no width, so that holds. */
  .foot .col a svg{width:15px;height:15px;flex-shrink:0;opacity:.8}
  .foot-bottom{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px;font-family:var(--font-body);font-size:12px;opacity:.65;margin-top:22px;letter-spacing:.04em}
  @media(max-width:820px){.foot{grid-template-columns:1fr 1fr;row-gap:36px}.foot-brand{grid-column:1 / -1;max-width:420px}}
  @media(max-width:480px){.foot{grid-template-columns:1fr}.foot-brand{grid-column:auto;max-width:none}}

  /* ---------- CONCIERGE CONTACT (direct WhatsApp / email — no form, no modal) ---------- */
  .concierge{display:flex;flex-wrap:wrap;gap:14px;justify-content:center;margin:30px 0 18px}
  .btn-contact{display:inline-flex;align-items:center;gap:10px;font-family:var(--font-body);font-weight:600;font-size:14.5px;letter-spacing:.01em;padding:15px 28px;border-radius:100px;min-height:44px;transition:transform .15s,background .2s,border-color .2s;text-decoration:none}
  .btn-contact svg{width:19px;height:19px;flex-shrink:0}
  .btn-contact.btn-whatsapp{background:#25623a;color:#fff}
  @media(hover:hover){.btn-contact.btn-whatsapp:hover{background:#1d4e2e;transform:translateY(-1px)}}
  .btn-contact.btn-email{background:rgba(247,242,231,.1);color:var(--cream);border:1px solid var(--line-light)}
  @media(hover:hover){.btn-contact.btn-email:hover{background:rgba(247,242,231,.18);border-color:var(--gold);transform:translateY(-1px)}}
  /* The form route. Outlined rather than filled so the WhatsApp button keeps visual
     primacy: WhatsApp is the faster path for anyone who can use it, and this is the
     alternative for buyers on a managed desktop who cannot. Uses --cream and
     --line-light directly, matching btn-email; the semantic --on-inverse tokens the
     dark-mode plan introduces do not exist yet. */
  .btn-contact.btn-form{background:transparent;color:var(--cream);border:1px solid var(--line-light)}
  @media(hover:hover){.btn-contact.btn-form:hover{background:rgba(247,242,231,.14);border-color:var(--gold);transform:translateY(-1px)}}
  /* Full-opacity cream, not the .78 alpha .quote uses for the same element. The two bands
     look alike but their backgrounds are nowhere near each other: .quote sits on --brown
     (#1a1410), where cream at .78 still clears 13:1, while .final sits on --olive-deep
     (#7d5a1e) and the same alpha blends down to #dcd0bb for 4.13:1 -- under the 4.5:1 AA
     floor, and this eyebrow is 11px/700, which is not "large text" at any size threshold.
     Dropping the alpha puts it at 5.61:1. Do not re-unify these two rules on the shared
     .78: the contrast depends on the band underneath, not on the element. */
  .final .eyebrow{color:var(--cream);display:block;margin-bottom:14px}
