/* ==========================================================================
   GBH custom components — CUSTOM BUILD layer.
   Everything here is new: Bexon has no native equivalent for Present vs
   Performing, Health Score, Priority Sequence, Snapshot findings, or the
   Discovery question-card flow. Built in Bexon's own visual language
   (same --tj-* tokens, same type scale, same spacing rhythm) rather than
   inventing a separate design system.
   Nav/footer here are deliberately simplified rewrites of Bexon's real
   header/footer markup — same look, without the mega-menu/hamburger/
   search-popup/GSAP stack (see migration register: dropped for robustness
   and load weight, per the brief's own performance/accessibility guidance).
   ========================================================================== */

*{box-sizing:border-box}
/* scroll-padding-top: 94px = .gbh-header .bar's 74px height + ~20px breathing
   room. Root cause of the cross-page navigation "jump" (GBH — Critical
   Functional Closure Pass, Part 10): .gbh-header is position:sticky;top:0,
   so a same/cross-page anchor link (e.g. business-snapshot.html's "Start My
   Blueprint" -> build-your-business.html#blueprint-preview, or "See Full
   Details") landed the target section flush with the viewport top, which
   the sticky header then immediately covered — reading as a visible
   post-load jump/snap even though no JS scroll logic was actually
   misbehaving. scroll-padding-top tells the browser's OWN native anchor-scroll
   (no JS involved) to stop short of the header on every anchor jump
   sitewide, on first load and on Back/Forward alike, so normal browser
   history/back behavior is untouched. */
html{scroll-behavior:smooth;scroll-padding-top:94px;overflow-x:hidden}
/* the off-canvas mobile nav panel sits at translateX(100%) when closed — correct,
   standard slide-in-menu technique — but that pushes it just past the right edge,
   which silently doubles document scrollWidth unless overflow-x is clipped here. */
body{font-size:17px;line-height:1.65;overflow-x:hidden}
.container{max-width:1180px} /* matches production's --wrap:1180px exactly — was 1240px, an invented width */
a{text-decoration:none}
img{max-width:100%;display:block}
/* trimmed 2026-08-27 (compactness pass): 120/64 read as unproductive empty space once
   the services grid and merged hero/proof section made the page's actual content much
   shorter — still generous editorial breathing room, just not excess. */
.section-pad{padding:92px 0}
@media (max-width:991px){ .section-pad{padding:72px 0} }
@media (max-width:575px){ .section-pad{padding:56px 0} }
.section-pad-sm{padding:56px 0}

/* ---------- eyebrow / kicker ----------
   The decorative prefix stroke (a small horizontal line before every
   eyebrow label) was removed site-wide (2026-08-29) per the "eyebrows
   read as plain text, no decorative dash" rule — this single shared
   rule change removes it from every page at once. The eyebrow text
   itself, its color, weight, and spacing are untouched. */
.gbh-eyebrow{display:inline-flex;align-items:center;gap:9px;font-family:var(--tj-ff-body);font-size:12.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--gbh-gold-deep);margin-bottom:16px}
.gbh-eyebrow.on-dark{color:var(--gbh-teal-on-dark)}
.gbh-lede{font-size:18px;color:var(--tj-color-text-body-3);max-width:580px;line-height:1.65}
.gbh-lede.on-dark{color:var(--gbh-on-dark-soft)}
.gbh-section-head{max-width:660px;margin-bottom:44px}
.gbh-section-head.center{margin-left:auto;margin-right:auto;text-align:center}
.gbh-section-head h2{font-size:clamp(28px,3.4vw,44px);font-weight:600;color:var(--gbh-navy);line-height:1.12;text-wrap:balance}
.gbh-section-head.on-dark h2{color:var(--gbh-on-dark)}

/* ---------- buttons (Bexon ships .tj-primary-btn; GBH adds the secondary) ---------- */
/* ---------- primary CTA — explicit override, not left to token cascade ----------
   Final approved spec: normal = bright-blue bg / dark-blue text.
   Hover = deliberate inversion — dark-blue bg / very-light-neutral text.
   Arrow icon-cap removed (2026-08-28 correction pass) — every .tj-primary-btn
   reads as a plain text label, no .btn-icon markup left anywhere to style.
   Shape corrected again same day (founder final call): full-pill/capsule
   (border-radius 50-100px) read as generic-SaaS/app-like, not the premium
   editorial/consulting look this site wants. Final standard is a soft
   rounded rectangle — height 52px, radius 14px, 26px horizontal padding,
   font-weight 600 — applied identically to primary and secondary so both
   are unmistakably the same button family. */
/* ONE canonical CTA size/alignment system (2026-08-30, final button-standard
   pass) — reference: the homepage "Start My Business Discovery" button,
   confirmed as 244x44 CSS px (the founder's reference screenshot was 2x/
   Retina). Fixed width, NOT label-dependent; flex-centered both axes; one
   size shared by every main CTA sitewide. Two color variants only — every
   dimensional/alignment property lives here once, never duplicated per-page
   or per-card. */
.tj-primary-btn,.tj-secondary-btn{
  display:flex !important;align-items:center;justify-content:center;text-align:center;
  width:244px;max-width:100%;min-height:44px;padding:10px 20px;box-sizing:border-box;
  border-radius:4px;font-family:var(--tj-ff-body);font-size:15px;font-weight:600;line-height:1.3;
  text-decoration:none;
}
@media (max-width:480px){ .tj-primary-btn,.tj-secondary-btn{width:100%} }

.tj-primary-btn{background:var(--gbh-gold) !important;color:var(--gbh-navy) !important;border:none;transition:background .2s ease,color .2s ease,transform .2s ease,box-shadow .2s ease !important}
.tj-primary-btn .btn-text,.tj-primary-btn .btn-text span{color:var(--gbh-navy) !important}
.tj-primary-btn:hover{background:var(--gbh-navy) !important;color:var(--gbh-paper-2) !important}
.tj-primary-btn:hover .btn-text,.tj-primary-btn:hover .btn-text span{color:var(--gbh-paper-2) !important}

.tj-secondary-btn{border:1.5px solid var(--gbh-navy);color:var(--gbh-navy);background:transparent;transition:.2s}
/* Long-label exception (2026-08-30, live-bug closure) — box stays the exact
   canonical 244x44; only this modifier's font-size shrinks so a longer label
   fits on one line instead of wrapping. Never changes width/height/radius. */
.tj-primary-btn.btn-tight-label,.tj-secondary-btn.btn-tight-label{font-size:11.5px;white-space:nowrap}
.tj-secondary-btn:hover{background:var(--gbh-line);color:var(--gbh-navy)}
.tj-secondary-btn.on-dark{border-color:var(--gbh-line-on-dark);color:var(--gbh-on-dark)}
.tj-secondary-btn.on-dark:hover{border-color:var(--gbh-on-dark);background:rgba(248,245,239,.06)}
.btn-row{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
@media (max-width:575px){ .btn-row{flex-direction:column;align-items:stretch} .btn-row a{justify-content:center} }

/* ---------- header (simplified rewrite) ---------- */
/* Header geometry corrected to match production's compact horizontal rhythm —
   production's real numbers: navshell min-height 72px, nav gap 16px, nav-cta
   padding 10px 14px. Previous pass used 88px/32px/a full 56px hero-sized button
   here, which is what caused the nav to wrap at desktop widths — that was an
   invented proportion, not a Bexon-required one. Fixed below; the full-width
   sticky-bar treatment itself (vs. production's floating rounded "pill" card)
   is kept as a deliberate Bexon-style visual choice — see report. */
.gbh-header{position:sticky;top:0;z-index:80;background:rgba(248,245,239,.88);border-bottom:1px solid var(--gbh-line)}
/* Frosted-glass blur moved off .gbh-header itself and onto a decorative ::before
   layer (2026-09-02, mobile-nav containing-block fix). backdrop-filter on an
   ancestor makes that ancestor the containing block for any position:fixed
   descendant — .gbh-nav is exactly that descendant at <=1060px widths, so its
   top:74px/bottom:0 were resolving against .gbh-header's own ~74px box instead
   of the viewport, collapsing the open mobile menu to a sliver instead of a
   full-height overlay. This pseudo-element reproduces the identical blur
   (same inset, same blur radius) without .gbh-header (or any other ancestor of
   .gbh-nav) carrying backdrop-filter, so .gbh-nav's fixed positioning is
   viewport-relative again. z-index:-1 keeps it behind the header's own content
   (.bar, brand, nav, CTA) — safe here, not a "sink below the document" risk,
   because .gbh-header already establishes its own stacking context (z-index:80
   above), so a negative z-index child is scoped inside that context and can
   only sink below OTHER CONTENT INSIDE THE HEADER, never below the page. */
.gbh-header::before{content:"";position:absolute;inset:0;z-index:-1;backdrop-filter:blur(14px);pointer-events:none}
.gbh-header .bar{display:flex;align-items:center;justify-content:space-between;height:74px;gap:16px}
.gbh-brand{display:flex;align-items:center;gap:14px;color:var(--gbh-navy);white-space:nowrap}
/* circular ring mark — restrained thin-outline ring with the initials inside, echoing
   the original GMH mark's circular language while staying clearly its own GBH identity;
   not a filled app-icon shape. Scaled up (correction pass) — the first version read as
   too small/weak next to the wordmark; bigger diameter, a slightly heavier ring, and
   more breathing room to the wordmark give it real presence without touching the
   74px header bar height it still fits inside comfortably.
   NOTE: this text-placeholder rule still serves every page that hasn't been migrated
   to the real logo asset yet (`<span class="mark">GBH</span>`) — see the `img.mark`
   override immediately below for the pages that already use the real image
   (assets/images/logos/gbh-mark.svg). Do not remove the border/flex/font properties
   here; only `img.mark` needs different treatment, not this shared base rule. */
.gbh-brand .mark{
  width:46px;height:46px;border-radius:50%;background:transparent;color:var(--gbh-navy);
  border:2px solid var(--gbh-navy);
  display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;
  font-family:var(--tj-ff-body);letter-spacing:.01em;flex:none;
}
/* Real-logo-asset override (header/footer presentation fix) — applies ONLY to an
   actual <img class="mark" src="assets/images/logos/gbh-mark.svg"> element, never to
   the text-placeholder <span class="mark"> pages above, so this cannot regress any
   page that hasn't been migrated to the real asset yet. The ring/letters/tagline are
   baked into the image itself, so the placeholder's border/flex-centering/font
   properties are wrong for it (they were producing a bordered box around an
   already-broken/mis-fit image) — object-fit:contain + no border is what a real
   image needs. background-color:transparent is required, not decorative:
   bootstrap.min.css defines `.mark,mark{background-color:var(--bs-highlight-bg)}`
   (its text-highlight utility, --bs-highlight-bg:#fff3cd) which collides with our
   unrelated reuse of the class name "mark" and was painting that cream color behind
   the logo. */
.gbh-brand img.mark{
  border:none;display:block;object-fit:contain;background-color:transparent;
}
/* Header-only presentation correction: the asset's own internal crop (see
   gbh-mark.svg's viewBox — trimmed ~13% of the outer transparent ring margin,
   same artwork/colors, no redesign) already makes the mark read fuller; this
   adds a small, header-scoped size increase on top (46px -> 50px, ~9%) so the
   lockup reads stronger next to the nav/CTA, per founder feedback that the
   mark felt visually weak. Deliberately scoped to img.mark only, so any page
   still on the text placeholder is completely unaffected, and the footer's
   real-asset mark (below) keeps its existing 46px size untouched.
   RING VISIBILITY FIX (2026-09-19, owner instruction — "restore the approved
   circular GBH mark"): the size bump above was never the real fix. Confirmed
   live, reproducibly: the asset's own ring (real vector paths, same
   colors/artwork, not a placeholder) has partial-alpha fill that visually
   disappears when composited directly against this header's translucent
   background (rgba(248,245,239,.88) + its own backdrop-filter blur) — an
   opaque white backing behind the mark restores it to fully visible, exactly
   as it renders against any solid background (confirmed by direct A/B
   screenshot comparison). This is a background-contrast fix, not a redesign:
   same file, same colors, same size — only an opaque circular backing added
   so the existing ring is actually visible instead of alpha-blending away. */
.gbh-header .gbh-brand img.mark{width:50px;height:50px;background:#fff;border-radius:50%}
/* single-line lockup (correction pass) — the previous version stacked a standalone
   "GBH" wordmark (heading-size) above a small "Get Business Handled" caption; the
   founder found that redundant next to the circular mark, which already says GBH.
   Now just one line: mark + "Get Business Handled". */
.gbh-brand .wordmark{font-family:var(--tj-ff-heading);font-weight:600;font-size:17px;letter-spacing:-.004em}
.gbh-nav{display:flex;align-items:center;gap:16px}
.gbh-nav a{font-family:var(--tj-ff-body);font-size:13.5px;font-weight:600;color:var(--tj-color-text-body-3);padding:6px 0;border-bottom:2px solid transparent;white-space:nowrap}
.gbh-nav a:hover,.gbh-nav a.active{color:var(--gbh-navy);border-color:var(--gbh-navy)}
.gbh-nav-toggle{display:none;width:40px;height:40px;border-radius:4px;border:1px solid var(--gbh-line-strong);background:var(--gbh-paper);color:var(--gbh-navy);align-items:center;justify-content:center;cursor:pointer;flex:none}
/* compact nav-row CTA — production's nav-cta is a compact rectangle inline with
   the links, not a hero-sized button. The full-size .tj-primary-btn stays as-is
   for the hero/final-CTA; this header-only variant keeps its bright-blue/dark-blue
   colors and hover-invert but at production's actual scale. Radius scaled down
   proportionally from the 14px/52px standard (roughly the same 14px:52px ratio,
   and matching .gbh-nav-toggle's own 9px radius right next to it) rather than
   reusing 14px outright, which would read far more rounded on a button this
   short than the main 52px standard does — same family, correct proportion.
   Soft pulse added (founder request) — it's the one CTA repeated on every
   page, so it carries the job of drawing the eye without shouting. A slow,
   low-opacity expanding ring in the existing azure accent, not a bounce/
   scale/color change — restrained enough to read as premium, still genuinely
   noticeable. Paused on hover (the invert transition already provides
   feedback there) and disabled entirely under prefers-reduced-motion. */
.gbh-header .tj-primary-btn{width:auto !important;min-width:0 !important;height:auto !important;min-height:0 !important;padding:9px 16px !important;font-size:13px !important;border-radius:4px !important;animation:gbh-cta-pulse 2.6s ease-in-out infinite}
.gbh-header .tj-primary-btn:hover{animation:none}
@keyframes gbh-cta-pulse{
  0%,100%{box-shadow:0 0 0 0 rgba(57,137,200,.38)}
  50%{box-shadow:0 0 0 7px rgba(57,137,200,0)}
}
@media (prefers-reduced-motion:reduce){ .gbh-header .tj-primary-btn{animation:none} }
@media (max-width:1060px){
  .gbh-nav{position:fixed;top:74px;left:0;right:0;bottom:0;background:var(--gbh-cream);flex-direction:column;align-items:flex-start;padding:24px;gap:2px;transform:translateX(100%);transition:transform .25s ease;overflow-y:auto;border-top:1px solid var(--gbh-line)}
  .gbh-nav.is-open{transform:translateX(0)}
  .gbh-nav a{width:100%;padding:15px 4px;border-bottom:1px solid var(--gbh-line);white-space:normal}
  .gbh-nav-toggle{display:flex}
  .gbh-header .bar > div:last-child .tj-primary-btn{display:none}
}
/* "Get Business Handled" is a longer string than the old "GBH" wordmark was, so the
   hide-on-narrow threshold widens accordingly to avoid crowding the compact CTA. */
@media (max-width:480px){
  .gbh-header .wordmark{display:none}
}

/* ---------- footer (simplified rewrite) ---------- */
.gbh-footer{background:var(--gbh-navy);color:var(--gbh-on-dark-soft);padding:76px 0 26px}
.gbh-footer .grid{display:grid;grid-template-columns:1.45fr 1fr 1fr 1fr;gap:40px;padding-bottom:44px;border-bottom:1px solid var(--gbh-line-on-dark)} /* matches production's footer-grid proportions exactly */
@media (max-width:800px){ .gbh-footer .grid{grid-template-columns:1fr 1fr;row-gap:32px} }
@media (max-width:480px){ .gbh-footer .grid{grid-template-columns:1fr} }
/* root cause of the footer brand stacking vertically (hierarchy cleanup pass): the
   generic ".gbh-footer a{display:block}" rule two lines below (meant for the footer's
   link lists) has higher specificity for the `display` property than the base
   ".gbh-brand{display:flex}" rule, since .gbh-brand alone is only a single class. This
   explicit override restores the same one-line mark+wordmark lockup already used in
   the header. */
.gbh-footer .gbh-brand{display:flex;align-items:center;gap:14px;color:var(--gbh-on-dark)}
/* on-dark treatment for the text-placeholder mark still used on pages not yet
   migrated to the real logo image (see img.mark override immediately below for
   the pages that are). */
.gbh-footer .gbh-brand .mark{border-color:var(--gbh-on-dark-soft);color:var(--gbh-on-dark)}
/* on-dark treatment for the REAL logo image only: the mark's own colors (navy
   ring/text) are too close to the footer's navy background to read (~#09223e
   mark vs #173B57 footer) — flatten it to solid white so it's legible. Scoped
   to img.mark so this never touches the text-placeholder rule above. */
.gbh-footer .gbh-brand img.mark{filter:brightness(0) invert(1)}
.gbh-footer p.tag{margin-top:14px;font-size:14px;color:var(--gbh-on-dark-faint);max-width:280px}
.gbh-footer h5{font-family:var(--tj-ff-body);font-size:12.5px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--gbh-on-dark);margin-bottom:16px}
.gbh-footer a{display:block;font-size:14px;color:var(--gbh-on-dark-faint);margin-bottom:11px}
.gbh-footer a:hover{color:var(--gbh-on-dark)}
.gbh-footer .bottom{display:flex;justify-content:space-between;padding-top:22px;font-size:12.5px;color:var(--gbh-on-dark-faint);flex-wrap:wrap;gap:8px}

/* ---------- hero rotating word ---------- */
.rotator{display:inline-block;position:relative;color:var(--gbh-gold-deep);font-style:italic}
.rotator .word{display:inline-block;opacity:0;transform:translateY(8px);animation:gbh-rotate 8s infinite;}
.rotator .word:nth-child(1){animation-delay:0s}
.rotator .word:nth-child(2){animation-delay:2s}
.rotator .word:nth-child(3){animation-delay:4s}
.rotator .word:nth-child(4){animation-delay:6s}
.rotator{min-width:8ch}
.rotator .word{position:absolute;left:0;white-space:nowrap}
.rotator .word:first-child{position:static}
@keyframes gbh-rotate{
  0%,3%{opacity:0;transform:translateY(8px)}
  8%,20%{opacity:1;transform:translateY(0)}
  25%,100%{opacity:0;transform:translateY(-8px)}
}
@media (prefers-reduced-motion:reduce){
  .rotator .word{animation:none;opacity:0;position:absolute}
  .rotator .word:first-child{opacity:1;position:static}
}

/* ---------- present vs performing ---------- */
.pvp{background:var(--gbh-navy);border-radius:32px;color:var(--gbh-on-dark);overflow:hidden}
.pvp-inner{padding:80px 56px}
@media (max-width:575px){ .pvp-inner{padding:52px 22px} }
.pvp-grid{display:grid;grid-template-columns:1fr 1fr;gap:2px;margin-top:48px;background:var(--gbh-line-on-dark);border-radius:20px;overflow:hidden}
@media (max-width:800px){ .pvp-grid{grid-template-columns:1fr} }
.pvp-col{background:#1F4864;padding:34px 30px}
.pvp-col.performing{background:#2A5170}
.pvp-col .tag{display:inline-flex;font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:6px 13px;border-radius:100px;margin-bottom:20px}
.pvp-col.present .tag{background:rgba(147,67,58,.18);color:#E4988D}
.pvp-col.performing .tag{background:rgba(0,191,255,.18);color:var(--gbh-teal-on-dark)}
.pvp-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 0;border-bottom:1px solid var(--gbh-line-on-dark);font-size:15px}
.pvp-row:last-child{border-bottom:0}
.pvp-row .label{color:var(--gbh-on-dark-soft);font-weight:600}
.pvp-row .state{font-size:12.5px;font-weight:700;padding:4px 11px;border-radius:100px;white-space:nowrap}
/* Present = neutral fact, never alarm-colored. Performing = real severity, set per row via .ok/.warn/.crit */
.pvp-col.present .state{background:rgba(248,245,239,.12);color:var(--gbh-on-dark-soft)}
.pvp-row .state.ok{background:rgba(220,228,232,.2);color:#DCE4E8}
.pvp-row .state.warn{background:rgba(102,119,133,.3);color:#B4C0C7}
.pvp-row .state.crit{background:rgba(0,191,255,.22);color:#00BFFF}

/* ---------- health dial ---------- */
.gbh-dial{border-radius:50%;display:flex;align-items:center;justify-content:center;flex:none}
.gbh-dial span{border-radius:50%;background:var(--gbh-paper);display:flex;align-items:center;justify-content:center;font-family:var(--tj-ff-heading);font-weight:600}
.gbh-dial.sm{width:58px;height:58px;background:conic-gradient(var(--gbh-gold) var(--pct,52%),var(--gbh-gold-wash) 0)}
.gbh-dial.sm span{width:46px;height:46px;font-size:14px}
.gbh-dial.lg{width:104px;height:104px;background:conic-gradient(var(--gbh-gold) var(--pct,58%),var(--gbh-gold-wash) 0)}
.gbh-dial.lg span{width:84px;height:84px;font-size:24px}

/* ---------- priority sequence ---------- */
/* fixed 2026-08-27: was hardcoded to 4 columns, which forced the 5th step (Manage &
   Scale) onto its own accidental second row at every desktop width. Now genuinely 5
   across on desktop; narrower breakpoints reflow intelligently. */
.sequence{display:grid;grid-template-columns:repeat(5,1fr);gap:22px;margin-top:48px}
@media (max-width:1100px){ .sequence{grid-template-columns:repeat(3,1fr);row-gap:36px} }
@media (max-width:650px){ .sequence{grid-template-columns:1fr 1fr;row-gap:32px} }
@media (max-width:420px){ .sequence{grid-template-columns:1fr} }
/* the fine rule that used to trail each number is gone (final structural pass, matching
   the same change in the services grid) — the numeral's own size/weight/color now
   carries the hierarchy on its own. */
.seq-step .n{font-family:var(--tj-ff-heading);font-size:17px;color:var(--gbh-gold-deep);font-weight:600;margin-bottom:14px;display:block}
.seq-step h4{font-family:var(--tj-ff-body);font-size:16.5px;font-weight:700;color:var(--gbh-navy);margin-bottom:8px}
.seq-step p{font-size:14px;color:var(--tj-color-text-body-3);margin:0}

/* ---------- generic card ---------- */
.gbh-card{background:var(--gbh-paper);border:1px solid var(--gbh-line);border-radius:4px;box-shadow:0 1px 2px rgba(23,32,46,.04),0 10px 28px -14px rgba(23,32,46,.16)}

/* ---------- feature / figure-out grid ---------- */
.figure-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;margin-top:52px}
@media (max-width:991px){ .figure-grid{grid-template-columns:1fr 1fr} }
@media (max-width:575px){ .figure-grid{grid-template-columns:1fr} }
.figure-card{padding:30px 26px}
.figure-card .ic{width:46px;height:46px;border-radius:12px;background:var(--gbh-gold-wash);color:var(--gbh-gold-deep);display:flex;align-items:center;justify-content:center;margin-bottom:20px;font-size:19px}
.figure-card h4{font-family:var(--tj-ff-body);font-size:16.5px;font-weight:700;color:var(--gbh-navy);margin-bottom:8px}
.figure-card p{font-size:14px;color:var(--tj-color-text-body-3);margin:0;line-height:1.6}

/* ---------- services: think/do split ---------- */
/* Open Columns (site-wide container cleanup) — replaces the rounded
   two-tone (paper/dark-navy) panel with two open columns on the page's own
   background. Separation now comes from generous column gap + typography/
   color contrast between the kickers, not a filled box or color inversion. */
.think-do{display:grid;grid-template-columns:1fr 1fr;column-gap:64px;margin-top:52px}
@media (max-width:860px){ .think-do{grid-template-columns:1fr;row-gap:40px} }
.td-col .kicker{display:inline-flex;font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;margin-bottom:18px}
.td-col.think .kicker{color:var(--tj-color-text-body-3)}
.td-col.do .kicker{color:var(--gbh-gold-deep)}
.td-col h3{font-family:var(--tj-ff-heading);font-size:26px;margin-bottom:12px;color:var(--gbh-navy)}
.td-col p.desc{color:var(--tj-color-text-body-3);margin-bottom:26px;min-height:56px}
.service-line{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:16px 0;border-bottom:1px solid var(--gbh-line)}
.service-line:last-child{border-bottom:0}
.service-line .name{font-family:var(--tj-ff-body);font-weight:700;color:var(--gbh-navy);font-size:15px}
.service-line .desc{font-size:13px;color:var(--tj-color-text-body-3);margin-top:3px}

/* ---------- discovery shell ---------- */
.discovery-shell{min-height:640px;display:grid;grid-template-columns:1fr 1.15fr;background:var(--gbh-paper);border:1px solid var(--gbh-line);border-radius:28px;overflow:hidden;box-shadow:0 8px 24px -8px rgba(23,32,46,.18),0 24px 48px -24px rgba(23,32,46,.22)}
@media (max-width:900px){ .discovery-shell{grid-template-columns:1fr} }
.discovery-side{background:var(--gbh-navy);color:var(--gbh-on-dark);padding:52px 44px;display:flex;flex-direction:column;justify-content:space-between}
.dp-list{display:flex;flex-direction:column;gap:2px;margin-top:38px}
.dp-item{display:flex;align-items:center;gap:14px;padding:12px 0;opacity:.4}
.dp-item.active{opacity:1}
.dp-item.done{opacity:.75}
.dp-item .b{width:26px;height:26px;border-radius:50%;border:1.5px solid var(--gbh-line-on-dark);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;flex:none}
.dp-item.active .b{background:var(--gbh-gold);border-color:var(--gbh-gold);color:#fff}
.dp-item.done .b{background:transparent;border-color:#9FCBA6;color:#9FCBA6}
.dp-item span{font-size:14.5px;font-weight:600}
.discovery-main{padding:60px 54px;display:flex;flex-direction:column;justify-content:center}
@media (max-width:575px){ .discovery-main,.discovery-side{padding:34px 24px} }
.progress-bar{height:5px;background:var(--gbh-line);border-radius:100px;overflow:hidden;margin-bottom:34px}
.progress-bar i{display:block;height:100%;background:var(--gbh-gold);border-radius:100px}
.discovery-main h2{font-family:var(--tj-ff-heading);font-size:clamp(23px,2.8vw,30px);margin-bottom:32px;max-width:480px;color:var(--gbh-navy)}
.q-options{display:flex;flex-direction:column;gap:12px;max-width:460px}
.q-option{border:1.5px solid var(--gbh-line);border-radius:14px;padding:17px 20px;display:flex;align-items:center;justify-content:space-between;cursor:pointer;background:var(--gbh-paper)}
.q-option:hover,.q-option.selected{border-color:var(--gbh-gold);background:var(--gbh-gold-wash)}
.q-option span{font-family:var(--tj-ff-body);font-weight:600;color:var(--gbh-navy);font-size:15px}
.q-option .radio{width:20px;height:20px;border-radius:50%;border:1.5px solid var(--gbh-line-strong);flex:none}
.q-option.selected .radio{border-color:var(--gbh-gold);background:var(--gbh-gold);box-shadow:inset 0 0 0 3px var(--gbh-paper)}
.discovery-nav{display:flex;justify-content:space-between;align-items:center;margin-top:40px;max-width:460px}
.discovery-nav .back{font-family:var(--tj-ff-body);font-size:13.5px;font-weight:700;color:var(--tj-color-text-body-3)}

/* ---------- snapshot ---------- */
.snap-header{display:flex;align-items:center;justify-content:space-between;gap:24px;flex-wrap:wrap;margin-bottom:40px;padding-bottom:30px;border-bottom:1px solid var(--gbh-line)}
.snap-health{display:flex;align-items:center;gap:16px;background:var(--gbh-paper);border:1px solid var(--gbh-line);border-radius:18px;padding:15px 22px}
.snap-health .lbl{font-family:var(--tj-ff-body);font-size:11.5px;font-weight:700;color:var(--tj-color-text-body-3);text-transform:uppercase;letter-spacing:.05em}
.snap-health .desc{font-size:13px;color:var(--gbh-navy);font-weight:600}
.snap-grid{display:grid;grid-template-columns:2fr 1fr;gap:26px;align-items:start}
@media (max-width:960px){ .snap-grid{grid-template-columns:1fr} }
.snap-card{background:var(--gbh-paper);border:1px solid var(--gbh-line);border-radius:18px;padding:28px;margin-bottom:20px}
.snap-card h3{font-family:var(--tj-ff-heading);font-size:20px;margin-bottom:18px;color:var(--gbh-navy)}
.attn-row{display:flex;align-items:flex-start;gap:14px;padding:16px 0;border-bottom:1px solid var(--gbh-line)}
.attn-row:last-child{border-bottom:0}
.attn-row .pill{font-family:var(--tj-ff-body);font-size:11px;font-weight:700;padding:4px 10px;border-radius:100px;flex:none;margin-top:2px;white-space:nowrap}
.attn-row .pill.crit{background:var(--gbh-crit-wash);color:var(--gbh-crit)}
.attn-row .pill.warn{background:var(--gbh-warn-wash);color:var(--gbh-warn)}
.attn-row .pill.ok{background:var(--gbh-ok-wash);color:var(--gbh-ok)}
.attn-row h5{font-family:var(--tj-ff-body);font-size:14.5px;font-weight:700;color:var(--gbh-navy);margin-bottom:4px}
.attn-row p{font-size:13.5px;color:var(--tj-color-text-body-3);margin:0}
.rm-phase{display:grid;grid-template-columns:70px 1fr;gap:16px;padding:18px 0;border-bottom:1px solid var(--gbh-line)}
.rm-phase:last-child{border-bottom:0}
.rm-phase .when{font-family:var(--tj-ff-heading);font-weight:600;color:var(--gbh-gold-deep);font-size:14px}
.rm-phase h5{font-family:var(--tj-ff-body);font-size:14.5px;font-weight:700;color:var(--gbh-navy);margin-bottom:4px}
.rm-phase p{font-size:13px;color:var(--tj-color-text-body-3);margin:0}
.snap-side .snap-card{position:sticky;top:110px}
.illustrative-tag{display:inline-block;font-family:var(--tj-ff-body);font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--tj-color-text-body-3);background:var(--gbh-paper-2);border:1px solid var(--gbh-line);padding:3px 9px;border-radius:100px;margin-bottom:18px}

/* ---------- blueprint product ---------- */
.blueprint-showcase{display:grid;grid-template-columns:.86fr 1.14fr;gap:60px;align-items:flex-start;margin-top:52px}
@media (max-width:991px){ .blueprint-showcase{grid-template-columns:1fr;gap:40px} }
.bp-mock{background:var(--gbh-paper);border:1px solid var(--gbh-line);border-radius:24px;overflow:hidden;box-shadow:0 8px 24px -8px rgba(23,32,46,.18),0 24px 48px -24px rgba(23,32,46,.22)}
.bp-mock-head{background:var(--gbh-navy);color:var(--gbh-on-dark);padding:22px 26px}
.bp-mock-head .k{font-family:var(--tj-ff-body);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--gbh-on-dark-faint);margin-bottom:6px;font-weight:700}
.bp-mock-head .v{font-family:var(--tj-ff-heading);font-size:20px}
.bp-mock-body{padding:24px 26px}
.bp-score{display:flex;align-items:center;gap:18px;margin-bottom:22px;padding-bottom:22px;border-bottom:1px solid var(--gbh-line)}
.bp-list-row{display:flex;align-items:center;gap:12px;padding:11px 0;border-bottom:1px solid var(--gbh-line);font-size:14px}
.bp-list-row:last-child{border-bottom:0}
.bp-list-row .dot{width:8px;height:8px;border-radius:50%;flex:none}
.bp-list-row .dot.crit{background:var(--gbh-crit)}
.bp-list-row .dot.warn{background:var(--gbh-warn)}
.bp-list-row .dot.ok{background:var(--gbh-ok)}
.bp-list-row .name{flex:1;font-family:var(--tj-ff-body);font-weight:600;color:var(--gbh-navy)}
.bp-list-row .pill{font-size:11.5px;font-weight:700;padding:3px 10px;border-radius:100px}
.bp-list-row .pill.crit{background:var(--gbh-crit-wash);color:var(--gbh-crit)}
.bp-list-row .pill.warn{background:var(--gbh-warn-wash);color:var(--gbh-warn)}
.bp-list-row .pill.ok{background:var(--gbh-ok-wash);color:var(--gbh-ok)}
.bp-mock-foot{padding:16px 26px;background:var(--gbh-paper-2);border-top:1px solid var(--gbh-line);font-size:12.5px;color:var(--tj-color-text-body-3)}
.bp-copy h3{font-family:var(--tj-ff-heading);font-size:28px;margin-bottom:16px;color:var(--gbh-navy)}
.bp-copy p{color:var(--tj-color-text-body-3);margin-bottom:26px;max-width:520px}
.bp-modules{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media (max-width:480px){ .bp-modules{grid-template-columns:1fr} }
.bp-module{border:1px solid var(--gbh-line);border-radius:14px;padding:18px 20px;background:var(--gbh-paper)}
.bp-module .n{font-family:var(--tj-ff-heading);color:var(--gbh-gold-deep);font-size:13px;font-weight:600;margin-bottom:6px}
.bp-module h5{font-family:var(--tj-ff-body);font-size:14.5px;font-weight:700;color:var(--gbh-navy);margin-bottom:4px}
.bp-module p{font-size:13px;color:var(--tj-color-text-body-3);margin:0}
.bp-price-note{margin-top:28px;padding:20px 24px;border-radius:16px;background:var(--gbh-gold-wash);display:flex;align-items:center;gap:18px;justify-content:space-between;flex-wrap:wrap}
.bp-price-note .amount{font-family:var(--tj-ff-heading);font-size:26px;color:var(--gbh-gold-deep)}
.bp-price-note p{font-size:13.5px;color:var(--gbh-navy);max-width:340px;margin:0}
.bp-roadmap{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:52px}
@media (max-width:800px){ .bp-roadmap{grid-template-columns:1fr} }
.bp-rm-card{background:var(--gbh-paper);border:1px solid var(--gbh-line);border-radius:18px;padding:26px}
.bp-rm-card .when{font-family:var(--tj-ff-heading);color:var(--gbh-gold-deep);font-weight:600;margin-bottom:10px}
.bp-rm-card h4{font-family:var(--tj-ff-body);font-size:16px;font-weight:700;color:var(--gbh-navy);margin-bottom:8px}
.bp-rm-card p{font-size:13.5px;color:var(--tj-color-text-body-3);margin:0}

/* ---------- faq (custom accordion, no JS library) ---------- */
.gbh-faq{max-width:780px;margin:0 auto}
.gbh-faq-item{border-bottom:1px solid var(--gbh-line)}
.gbh-faq-q{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:22px 2px;cursor:pointer;font-family:var(--tj-ff-body);font-weight:700;color:var(--gbh-navy);font-size:16px}
.gbh-faq-q .ic{flex:none;width:22px;height:22px;position:relative}
.gbh-faq-q .ic::before,.gbh-faq-q .ic::after{content:"";position:absolute;background:var(--gbh-gold-deep);top:50%;left:50%;transform:translate(-50%,-50%)}
.gbh-faq-q .ic::before{width:14px;height:2px}
.gbh-faq-q .ic::after{width:2px;height:14px;transition:transform .2s}
.gbh-faq-item.open .gbh-faq-q .ic::after{transform:translate(-50%,-50%) rotate(90deg) scaleY(0)}
.gbh-faq-a{max-height:0;overflow:hidden;transition:max-height .25s ease}
.gbh-faq-item.open .gbh-faq-a{max-height:240px}
.gbh-faq-a p{padding:0 2px 22px;color:var(--tj-color-text-body-3);font-size:14.5px;max-width:640px;margin:0}

/* ---------- final CTA ---------- */
.gbh-final-cta{background:linear-gradient(135deg,#2A5170,#173B57);border-radius:4px;color:var(--gbh-on-dark);text-align:center;padding:68px 40px;position:relative;overflow:hidden}
.gbh-final-cta::before{content:"";position:absolute;inset:0;background:radial-gradient(560px 280px at 15% 0%,rgba(31,72,100,.45),transparent 70%),radial-gradient(480px 260px at 88% 100%,rgba(220,228,232,.1),transparent 70%)}
.gbh-final-cta > *{position:relative}
.gbh-final-cta h2{color:var(--gbh-on-dark);max-width:620px;margin:0 auto 16px;font-family:var(--tj-ff-heading);font-size:clamp(26px,3.2vw,38px)}
.gbh-final-cta p{color:var(--gbh-on-dark-soft);max-width:500px;margin:0 auto 32px;font-size:16.5px}
.gbh-final-cta .btn-row{justify-content:center}

/* ---------- proof/trust ---------- */
.proof-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:56px;align-items:center}
@media (max-width:900px){ .proof-grid{grid-template-columns:1fr;gap:36px} }
.quote-card{padding:40px}
.quote-card blockquote{font-family:var(--tj-ff-heading);font-size:23px;line-height:1.45;color:var(--gbh-navy);font-style:italic;margin:0 0 22px}
.quote-card cite{font-style:normal;font-size:13.5px;color:var(--tj-color-text-body-3);font-weight:600}
.trust-stats{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.trust-stat{background:var(--gbh-paper-2);border:1px solid var(--gbh-line);border-radius:16px;padding:22px}
.trust-stat strong{display:block;font-family:var(--tj-ff-heading);font-size:16px;color:var(--gbh-navy);line-height:1.3}
.trust-stat span{font-size:12.5px;color:var(--tj-color-text-body-3);font-weight:600}

/* ---------- crumb / page hero ---------- */
.page-hero{padding:56px 0 8px}
.crumb{display:flex;align-items:center;gap:8px;font-family:var(--tj-ff-body);font-size:13px;color:var(--tj-color-text-body-2);margin-bottom:20px}
.crumb a{color:var(--tj-color-text-body-3);font-weight:600}
.page-hero h1{font-family:var(--tj-ff-heading);font-size:clamp(32px,4.4vw,54px);color:var(--gbh-navy);max-width:760px;line-height:1.08}

/* ---------- reveal: pure CSS, no JS dependency, cannot get stuck invisible ---------- */
.reveal{opacity:1;transform:none;animation:gbh-fade-up .5s ease both}
@media (prefers-reduced-motion:reduce){ .reveal{animation:none} }
@keyframes gbh-fade-up{ from{opacity:0;transform:translateY(12px)} to{opacity:1;transform:none} }

/* ---------- honest photo placeholder (Bexon ships no real photography — see migration register) ---------- */
.photo-placeholder{
  position:relative;border-radius:24px;overflow:hidden;min-height:260px;
  background:repeating-linear-gradient(135deg,#EDE6D8 0 14px,#E4D5BE 14px 28px);
  border:1.5px dashed var(--gbh-line-strong);
  display:flex;align-items:flex-end;padding:22px;
}
.photo-placeholder .cap{background:rgba(23,32,46,.86);color:#fff;font-family:var(--tj-ff-body);font-size:12.5px;font-weight:600;padding:9px 14px;border-radius:10px;max-width:80%}
.photo-placeholder .cap b{display:block;font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--gbh-teal-on-dark);margin-bottom:3px}

/* ---------- elegant photo-direction frame (v2 — replaces the striped placeholder) ---------- */
/* A soft, art-directed panel standing in for a real photo: quiet tonal gradient (no busy
   pattern), a refined caption in the editorial voice of a real shot list, bottom-anchored
   like a magazine credit line. Reads as intentional direction, not a broken image. */
.photo-frame{
  position:relative;border-radius:4px;overflow:hidden;
  background:linear-gradient(150deg,#EFE7D9 0%,#E6D8C1 55%,#D8C4A3 100%);
}
.photo-frame::before{
  content:"";position:absolute;inset:0;
  background:radial-gradient(120% 90% at 15% 10%,rgba(255,255,255,.55),transparent 60%);
}
.photo-frame::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:46%;
  background:linear-gradient(to top,rgba(23,32,46,.72),transparent);
}
.photo-frame .direction{
  position:absolute;left:26px;right:26px;bottom:22px;z-index:1;color:#fff;
}
.photo-frame .direction .k{font-family:var(--tj-ff-body);font-size:10.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:#E4CFA8;margin-bottom:7px}
.photo-frame .direction p{font-family:var(--tj-ff-body);font-size:13px;line-height:1.55;color:rgba(255,255,255,.88);max-width:420px;margin:0}
/* Reusable on-dark outcome list (2026-08-30) — same checkmark/divider-row
   grammar as .tier-includes li, adapted for dark panels, so this becomes a
   standard "service outcome" pattern rather than a one-off. */
.photo-frame .direction .outcome-list{list-style:none;margin:14px 0 0;padding:0;max-width:420px}
.photo-frame .direction .outcome-list li{display:flex;align-items:flex-start;gap:9px;font-family:var(--tj-ff-body);font-size:13px;color:rgba(255,255,255,.88);padding:7px 0;border-top:1px solid rgba(255,255,255,.14)}
.photo-frame .direction .outcome-list li:first-child{border-top:0}
.photo-frame .direction .outcome-list li i{flex:none;margin-top:3px;font-size:10px;color:#E4CFA8}
.photo-frame.dark{background:linear-gradient(150deg,#2A5170 0%,#173B57 55%,#102E45 100%)}
.photo-frame.dark::before{background:radial-gradient(120% 90% at 85% 8%,rgba(255,255,255,.10),transparent 60%)}

/* ---------- open editorial offer grid, 6 items, 3x2 (2026-08-27 consolidated pass) ----------
   Six items divide evenly into a clean 3x2 grid — no empty slot risk, so back to CSS
   grid (simpler than the flex-wrap-centering trick a 5-item list needed). A single
   bottom rule under every item (restored per explicit founder direction) is the only
   divider — no vertical lines, no boxed cells, no card backgrounds. */
.offer-list{display:grid;grid-template-columns:repeat(3,1fr);column-gap:56px;row-gap:40px}
.offer-row{
  display:flex;flex-direction:column;gap:12px;
  padding-bottom:26px;border-bottom:1px solid var(--gbh-line);
  text-decoration:none;color:var(--gbh-navy);position:relative;
}
/* soft hover wash (final polish pass) — an absolutely-positioned pseudo-element, not a
   change to the row's own box, so it can't affect the grid's sizing/alignment. Invisible
   at rest (opacity:0), so there's no static "card" look — purely a hover affordance. */
.offer-row::before{
  content:"";position:absolute;inset:-14px -18px -14px -18px;z-index:-1;
  background:var(--gbh-gold-wash);border-radius:14px;opacity:0;
  transition:opacity .25s ease;pointer-events:none;
}
.offer-row:hover::before{opacity:1}
/* alternating number tone (same navy/blue-gray rhythm the Process section already
   uses) — restrained color differentiation across the six items, no new hues. */
.offer-row .row-num{font-family:var(--tj-ff-heading);font-size:19px;color:var(--gbh-gold-deep);font-weight:600;transition:color .2s ease}
.offer-row:nth-child(even) .row-num{color:var(--gbh-terracotta-deep)}
.offer-row:hover .row-num{color:var(--gbh-navy)}
.offer-row .problem{font-family:var(--tj-ff-body);font-size:12.5px;font-weight:700;color:var(--gbh-terracotta-deep);font-style:italic}
.offer-row h3{font-family:var(--tj-ff-heading);font-size:19px;color:var(--gbh-navy);font-weight:600;line-height:1.25}
.offer-row p{font-size:13.5px;color:var(--tj-color-text-body-3);line-height:1.55;margin:0}
.offer-row .go{
  display:flex;align-items:center;gap:9px;font-family:var(--tj-ff-body);font-size:13px;font-weight:700;color:var(--gbh-navy);
  white-space:nowrap;margin-top:auto;padding-top:6px;transition:color .2s ease;
}
.offer-row:hover .go{color:var(--gbh-deep-1)}
.offer-row .go svg{width:14px;height:14px;transition:transform .2s;flex:none}
.offer-row:hover .go svg{transform:translate(3px,-3px)}
@media (max-width:900px){ .offer-list{grid-template-columns:1fr 1fr;column-gap:44px;row-gap:36px} }
@media (max-width:600px){ .offer-list{grid-template-columns:1fr;row-gap:32px} }

/* contextual Discovery CTA, moved into the section intro (final polish pass) — replaces
   the standalone post-services CTA block entirely. Sits beside the intro copy at desktop
   width; the left rule is the one deliberate divider distinguishing "read about the
   method" from "skip ahead and start," not decoration. */
.intro-discovery-cta{
  display:flex;flex-direction:column;align-items:flex-start;gap:11px;
  padding-left:28px;border-left:1px solid var(--gbh-line);
  /* row is now align-items-start (was align-items-end, which bottom-anchored this
     column against the much taller intro block). This margin-top is the alignment
     correction: it drops the CTA past the eyebrow so it doesn't sit awkwardly level
     with it, landing roughly beside the heading/upper paragraph instead — not top,
     not bottom. */
  margin-top:190px;
}
.intro-discovery-cta .idc-label{font-family:var(--tj-ff-heading);font-size:16px;font-weight:600;color:var(--gbh-navy);line-height:1.3}
.intro-discovery-cta .idc-note{font-size:12px;color:var(--tj-color-text-body-3);line-height:1.3}
@media (max-width:991px){
  .intro-discovery-cta{padding-left:0;border-left:0;padding-top:22px;border-top:1px solid var(--gbh-line);margin-top:8px}
}


/* ---------- why / split-image editorial section ---------- */
.why-split{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:center}
@media (max-width:900px){ .why-split{grid-template-columns:1fr;gap:36px} }
.why-points{display:flex;flex-direction:column;gap:0}
.why-point{padding:22px 0;border-bottom:1px solid var(--gbh-line)}
.why-point:first-child{padding-top:0}
.why-point:last-child{border-bottom:0}
.why-point h4{font-family:var(--tj-ff-heading);font-size:20px;color:var(--gbh-navy);margin-bottom:6px;font-weight:600}
.why-point p{font-size:14.5px;color:var(--tj-color-text-body-3);margin:0;max-width:420px}

/* 2-column opt-in variant, toggled per-page with .why-2col on .why-points.
   Handles any item count: an odd count leaves its last item spanning the
   full width below a clean 2-column block; an even count needs its last
   ROW (the final two items) to both lose their divider, not just the one
   true last-child .why-point already zeroes out for the single-column case. */
.why-points.why-2col{display:grid;grid-template-columns:1fr 1fr;column-gap:56px}
.why-points.why-2col .why-point:last-child:nth-child(odd){grid-column:1/-1}
.why-points.why-2col .why-point:nth-last-child(2):nth-child(odd){border-bottom:0}
@media (max-width:700px){
  .why-points.why-2col{grid-template-columns:1fr}
  .why-points.why-2col .why-point:last-child:nth-child(odd){grid-column:auto}
  .why-points.why-2col .why-point:nth-last-child(2):nth-child(odd){border-bottom:1px solid var(--gbh-line)}
}

.hero-visual-wrap{position:relative}
.hero-stat-chip{
  position:absolute;left:24px;top:24px;z-index:2;
  background:rgba(255,255,255,.92);backdrop-filter:blur(6px);border-radius:16px;padding:14px 18px;
  display:flex;align-items:center;gap:12px;box-shadow:0 10px 30px -10px rgba(23,32,46,.4);
}
.hero-stat-chip .bars{display:flex;align-items:flex-end;gap:3px;height:28px}
.hero-stat-chip .bars i{width:5px;border-radius:2px 2px 0 0;background:var(--gbh-gold-wash);display:block}
.hero-stat-chip .bars i:last-child{background:var(--gbh-navy)}
.hero-stat-chip .txt{font-family:var(--tj-ff-body)}
.hero-stat-chip .txt b{display:block;font-size:12.5px;font-weight:700;color:var(--gbh-navy)}
.hero-stat-chip .txt span{font-size:10.5px;color:var(--tj-color-text-body-3);font-weight:600}

/* ==========================================================================
   VISUAL ENRICHMENT PASS — decorative motifs, texture, reveal motion.
   Built in pure CSS rather than fighting Bexon's color-locked demo SVGs
   (its blur-shape assets hardcode Bexon's own teal fill) — same visual
   idea (soft ambient glow, dot-grid texture, layered composition),
   GBH's own palette, full control. Real Bexon SVGs used directly only
   where they're already colorable (star.svg is fill="white", used on dark).
   ========================================================================== */

/* ambient blurred glow shapes — the Bexon "soft color pool behind content" motif */
.deco-blur{position:absolute;border-radius:50%;filter:blur(60px);pointer-events:none;z-index:0}
.deco-blur.slow{animation:gbh-drift 14s ease-in-out infinite}
@keyframes gbh-drift{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(14px,-10px) scale(1.06)}}
@media (prefers-reduced-motion:reduce){ .deco-blur.slow{animation:none} }

/* dot-grid texture — Bexon's pattern-2/pattern-3 motif, recreated in CSS for full color control */
.deco-dots{
  position:absolute;inset:0;pointer-events:none;z-index:0;
  background-image:radial-gradient(rgba(23,32,46,.14) 1.4px, transparent 1.4px);
  background-size:22px 22px;
  mask-image:radial-gradient(ellipse 60% 60% at 50% 40%, black 40%, transparent 78%);
}
.deco-dots.on-dark{background-image:radial-gradient(rgba(248,245,239,.14) 1.4px, transparent 1.4px)}

/* the oversized ghost-numeral treatment (previous pass) is retired for the services
   grid (2026-08-27 compactness pass): at 3-column width a giant background numeral
   would crowd the now-narrower cells. Each cell instead gets the same compact
   number+rule treatment as the Process section — see .row-num below. */

/* shot-spec overlay — crop marks + a compositional icon guide, so the placeholder reads as
   a specified shot (photographer's contact-sheet convention) rather than a stand-in graphic.
   Deliberately not photorealistic — avoids fabricating a fake human while still making the
   intended composition (who, where, how cropped) unmistakable. */
.shot-spec-mark{position:absolute;width:18px;height:18px;border-color:rgba(255,255,255,.55);z-index:2;pointer-events:none}
.shot-spec-mark.tl{top:16px;left:16px;border-top:1.5px solid;border-left:1.5px solid}
.shot-spec-mark.tr{top:16px;right:16px;border-top:1.5px solid;border-right:1.5px solid}
.shot-spec-mark.bl{bottom:16px;left:16px;border-bottom:1.5px solid;border-left:1.5px solid}
.shot-spec-mark.br{bottom:16px;right:16px;border-bottom:1.5px solid;border-right:1.5px solid}
.photo-frame.dark .shot-spec-mark,.hero-inset-tile .shot-spec-mark{border-color:rgba(255,255,255,.3)}
.shot-slate{
  position:absolute;top:16px;left:50%;transform:translateX(-50%);z-index:2;
  font-family:var(--tj-ff-body);font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:rgba(255,255,255,.65);
}
.shot-figure{position:absolute;z-index:1;color:rgba(255,255,255,.5);display:flex;align-items:flex-end;gap:14px}
.shot-figure i{display:block}
.shot-figure .lg{font-size:64px}
.shot-figure .sm{font-size:40px;opacity:.75}
/* frame gets too short on mobile to hold both the icon guide and the (longer) caption
   without them colliding — caption wins, icon guide drops */
@media (max-width:575px){ .shot-figure{display:none} }

/* photo-frame on-load reveal — a curtain wipe, once, on page load (not scroll-linked, can't get stuck) */
.photo-frame{animation:gbh-wipe .9s cubic-bezier(.65,0,.35,1) both}
@keyframes gbh-wipe{ from{clip-path:inset(0 0 0 100%)} to{clip-path:inset(0 0 0 0)} }
@media (prefers-reduced-motion:reduce){ .photo-frame{animation:none} }

/* layered hero composition: inset tile overlapping the main frame, asymmetric offset.
   (unused since the proprietary-visualization pass replaced the photo composition —
   left in place, harmless, in case a future pass reintroduces a layered photo tile) */
.hero-inset-tile{
  position:absolute;left:-34px;bottom:-30px;z-index:3;width:44%;aspect-ratio:1/1.05;
  border-radius:20px;overflow:hidden;box-shadow:0 20px 44px -14px rgba(23,32,46,.4);
  border:5px solid var(--gbh-cream);
  animation:gbh-wipe 1.1s .25s cubic-bezier(.65,0,.35,1) both;
}
@media (prefers-reduced-motion:reduce){ .hero-inset-tile{animation:none} }
@media (max-width:600px){ .hero-inset-tile{width:48%;left:-14px;bottom:-22px} }
.hero-badge-accent{position:absolute;top:-14px;left:-40px;width:28px;height:28px;opacity:.85;z-index:2}

/* stat-chip bars: grow in on load */
.hero-stat-chip .bars i{animation:gbh-grow .7s .5s cubic-bezier(.2,.8,.2,1) both}
.hero-stat-chip .bars i:nth-child(2){animation-delay:.58s}
.hero-stat-chip .bars i:nth-child(3){animation-delay:.66s}
.hero-stat-chip .bars i:nth-child(4){animation-delay:.74s}
.hero-stat-chip .bars i:nth-child(5){animation-delay:.82s}
@keyframes gbh-grow{ from{transform:scaleY(0);transform-origin:bottom} to{transform:scaleY(1);transform-origin:bottom} }
@media (prefers-reduced-motion:reduce){ .hero-stat-chip .bars i{animation:none} }

/* offer cell hover: the cell itself is the visual object, no floating thumbnail card —
   a quiet background wash, the row-num's rule darkening, typography shift, and arrow
   movement (all defined above/below) are the entire hover vocabulary here. */
.offer-row h3{transition:letter-spacing .25s ease}
.offer-row:hover h3{letter-spacing:.005em}

/* WHY — full-bleed dark editorial section */
.why-dark{background:var(--gbh-navy);color:var(--gbh-on-dark);position:relative;overflow:hidden}
.why-dark .why-point{border-bottom-color:var(--gbh-line-on-dark)}
.why-dark .why-point h4{color:var(--gbh-on-dark)}
.why-dark .why-point p{color:var(--gbh-on-dark-soft)}
.why-dark .pull-quote blockquote{color:var(--gbh-on-dark)}
/* Scoped to this section only (2026-08-30, Confidentiality & Access addition)
   — a fourth item joined the list, so padding is tightened slightly here to
   keep the section from growing substantially taller. The shared .why-point
   rule (used by the industry pages' own "why" sections) is untouched. */
.why-dark .why-point{padding:17px 0}

/* ==========================================================================
   PROPRIETARY VISUAL SYSTEM — replaces the photography-placeholder pass.
   One composition per section, built from type/line/SVG, not photography
   and not a card wall. Reuses existing GBH product language (Business
   Health, Present vs Performing™, Priority Sequence™) — no new methodology.
   ========================================================================== */

/* ---------- hero: Discovery -> Analysis -> Snapshot -> Blueprint -> Progression ----------
   (2026-08-28) Replaces the Business Health "64/100" score entirely — GBH Discovery does
   not calculate a numerical business-health percentage, so no visual here should imply
   one. This shows what happens to a customer's information instead: Discovery collects
   it, GBH reviews/researches it, a Snapshot surfaces preliminary signals, a Blueprint
   turns that into recommendations + a prioritized roadmap, and an illustrative
   progression shows how implementing those priorities can move a business toward a
   stronger operating position. No score, no gauge, no percentage, no revenue numbers,
   no guarantee language. Panel treatment (cooler blue-gray gradient, soft ambient
   shadow, rounded corners) carried over from the prior Business Health panel so the
   hero's overall visual weight/footprint doesn't change. */
.dbp-panel{
  position:relative;border-radius:4px;overflow:hidden;
  background:linear-gradient(155deg,#F7F8F7 0%,#EEF1F2 55%,#E7ECEE 100%);
  padding:38px 34px;box-shadow:0 24px 64px -36px rgba(23,59,87,.28);
}
.dbp-panel::before{content:"";position:absolute;inset:0;background:radial-gradient(115% 85% at 12% 6%,rgba(255,255,255,.75),transparent 58%),radial-gradient(75% 55% at 92% 100%,rgba(102,119,133,.09),transparent 70%);pointer-events:none}
.dbp-fine{position:relative;z-index:1;font-family:var(--tj-ff-body);font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:rgba(23,59,87,.58);margin-top:12px;line-height:1.5}

/* ---- layout: main stage area (left) + progression rail (right) ---- */
.dbp-body{position:relative;z-index:1;display:flex;gap:30px;align-items:flex-start}
.dbp-stage-area{flex:1 1 auto;min-width:0}
.dbp-progression{flex:0 0 150px;padding-left:24px;border-left:1px solid var(--gbh-line-strong)}

/* ---- stage content: label + rows/lines ----
   Default (no JS / ".dbp-armed" not yet added): every stage stacks in normal flow, all
   four fully visible — this IS the fail-safe static state. Once armed, each stage is
   pulled out of flow (absolute, stacked on top of each other in a fixed-height area)
   and only the ".is-active" one is shown; JS swaps which one that is as the sequence
   plays. The armed/active rules are declared after the plain ones so they win. */
.dbp-stage-label{font-family:var(--tj-ff-body);font-size:12px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--gbh-terracotta-deep);margin-bottom:16px}
.dbp-stage + .dbp-stage{margin-top:22px}
.dbp-line{font-family:var(--tj-ff-heading);font-size:16.5px;color:var(--gbh-navy);margin:0 0 12px;line-height:1.5}
.dbp-line:last-child{margin-bottom:0}
.dbp-row{display:flex;align-items:baseline;justify-content:space-between;gap:14px;padding:9px 0}
.dbp-row b{font-family:var(--tj-ff-body);font-size:14px;font-weight:700;letter-spacing:.03em;color:var(--gbh-navy);flex:1 1 auto}
.dbp-row span{font-family:var(--tj-ff-body);font-size:12.5px;font-weight:600;color:var(--tj-color-text-body-3);text-align:right;flex:none;white-space:nowrap}

/* ---- progression rail: a vertical stepper, not a chart. Discrete step-colors (see
   note below) reveal top-to-bottom as Blueprint outputs appear alongside it — this is
   the "the two systems communicate" requirement. Default state shows every label,
   dots neutral — a complete, readable static diagram if JS never runs. ---- */
.dbp-rail{display:flex;flex-direction:column;align-items:flex-start}
.dbp-point{display:flex;align-items:center;gap:10px}
.dbp-dot{width:8px;height:8px;border-radius:50%;background:var(--gbh-line-strong);flex:none;transition:background .3s ease,box-shadow .3s ease}
.dbp-plabel{font-family:var(--tj-ff-body);font-size:10.5px;font-weight:600;letter-spacing:.02em;color:#57666f;line-height:1.3}
.dbp-point.is-end .dbp-plabel{font-weight:700;color:var(--gbh-navy)}
.dbp-connector{width:1.5px;height:18px;background:var(--gbh-line-strong);margin-left:3.25px;transition:background .4s ease}
.dbp-progression-caption{margin-top:14px;font-family:var(--tj-ff-body);font-size:10.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--gbh-navy)}

/* Discrete "status" colors for the progression rail only — a deliberate, narrow,
   founder-approved exception to the site's navy/blue-gray/single-accent palette.
   Revised 2026-08-28 (color-treatment update): moved from a muted amber->green->navy
   arc to a fuller, more energetic multi-color progression per founder direction —
   light blue -> pink -> warm coral -> gold/yellow -> lime -> green -> teal -> bright
   blue -> GBH deep blue. Each stage's dot AND title share the exact same color, so the
   color itself (not a glow effect) is what reads as "this checkpoint is reached." Vivid
   but deliberately not neon/fluorescent — no box-shadow glow, no rainbow gradient
   across the label text, one solid color per stage. Not used anywhere else on the
   page. Connectors stay a neutral, subdued tone even when lit (see below) so the
   colored dots/titles — not the rail itself — stay the focal point. */
.dbp-point[data-cp="start"].is-lit .dbp-dot{background:#2C82B5}
.dbp-point[data-cp="start"].is-lit .dbp-plabel{color:#2C82B5}
.dbp-point[data-cp="1"].is-lit .dbp-dot{background:#C43D74}
.dbp-point[data-cp="1"].is-lit .dbp-plabel{color:#C43D74}
.dbp-point[data-cp="2"].is-lit .dbp-dot{background:#D4622E}
.dbp-point[data-cp="2"].is-lit .dbp-plabel{color:#D4622E}
.dbp-point[data-cp="3"].is-lit .dbp-dot{background:#A16207}
.dbp-point[data-cp="3"].is-lit .dbp-plabel{color:#A16207}
.dbp-point[data-cp="4"].is-lit .dbp-dot{background:#6B8A28}
.dbp-point[data-cp="4"].is-lit .dbp-plabel{color:#6B8A28}
.dbp-point[data-cp="5"].is-lit .dbp-dot{background:#2F8F52}
.dbp-point[data-cp="5"].is-lit .dbp-plabel{color:#2F8F52}
.dbp-point[data-cp="6"].is-lit .dbp-dot{background:#1F8478}
.dbp-point[data-cp="6"].is-lit .dbp-plabel{color:#1F8478}
.dbp-point[data-cp="7"].is-lit .dbp-dot{background:#0E7FA3}
.dbp-point[data-cp="7"].is-lit .dbp-plabel{color:#0E7FA3}
.dbp-point[data-cp="final"].is-lit .dbp-dot{background:var(--gbh-navy)}
.dbp-point[data-cp="final"].is-lit .dbp-plabel{color:var(--gbh-navy)}
/* the connector, once lit, only signals "progress happened here" — a quiet
   neutral step up from the unlit line-strong tone, deliberately not colorful. */
.dbp-connector.is-lit{background:#9FB0B8}

/* ---------- sequenced reveal, gated behind JS + viewport entry ----------
   Same fail-safe pattern established for the previous Business Health animation:
   default = fully visible, no animation (what renders if JS never runs at all). JS
   adds ".dbp-armed" the moment it confirms it can safely run the sequence (only then
   does anything go to a hidden/start state), then ".dbp-run" plus per-stage
   ".is-active" / per-point ".is-lit" classes as the sequence actually plays. A hard
   fallback timer guards the one real risk (the IntersectionObserver never firing) —
   see gbh-app.js. */
/* Centers each stage's content vertically within .dbp-stage-area's box (which JS
   sizes to the tallest stage — see gbh-app.js's dbpMeasureStageHeight). Shorter
   stages (e.g. 4-line Discovery) were previously top-pinned inside that box, leaving
   a large dead zone below them; centering distributes the natural height difference
   as breathing room above and below instead of one empty gap at the bottom. Harmless
   in the non-armed fallback (height:auto there, so centering has nothing to do). */
.dbp-stage{opacity:1;display:flex;flex-direction:column;justify-content:center}
.dbp-line,.dbp-row{opacity:1}
.dbp-point .dbp-dot,.dbp-connector{opacity:1}

.dbp-panel.dbp-armed .dbp-stage-area{position:relative;min-height:360px}
.dbp-panel.dbp-armed .dbp-stage{position:absolute;inset:0;opacity:0;transition:opacity .5s ease}
.dbp-panel.dbp-armed .dbp-stage + .dbp-stage{margin-top:0}
.dbp-panel.dbp-armed .dbp-stage.is-active{opacity:1}
.dbp-panel.dbp-armed .dbp-line,.dbp-panel.dbp-armed .dbp-row{opacity:0;transform:translateY(5px);transition:opacity .35s ease,transform .35s ease}
.dbp-panel.dbp-armed .dbp-stage.is-active .dbp-line.is-shown,
.dbp-panel.dbp-armed .dbp-stage.is-active .dbp-row.is-shown{opacity:1;transform:none}
.dbp-panel.dbp-armed .dbp-fine{opacity:0;transition:opacity .4s ease}
.dbp-panel.dbp-armed .dbp-stage.is-active .dbp-fine.is-shown{opacity:1}

@media (prefers-reduced-motion:reduce){
  /* JS never arms the sequence at all when this is set (see gbh-app.js) — this rule is
     a belt-and-suspenders guarantee of the same final state regardless. */
  .dbp-panel.dbp-armed .dbp-stage-area{min-height:0}
  .dbp-panel.dbp-armed .dbp-stage{position:relative;opacity:1;inset:auto}
  .dbp-panel.dbp-armed .dbp-stage + .dbp-stage{margin-top:26px}
  .dbp-panel.dbp-armed .dbp-line,.dbp-panel.dbp-armed .dbp-row,.dbp-panel.dbp-armed .dbp-fine{opacity:1;transform:none}
  /* Static fallback (reduced-motion or JS never runs): every checkpoint is "reached"
     at once, so show the complete colorful progression directly rather than the
     flattened single-navy treatment this used before the color-treatment update —
     the founder's "by the final state, the complete colorful progression should be
     visible" applies here too, not only to the end of the JS-driven animation. */
  .dbp-point[data-cp="start"] .dbp-dot{background:#2C82B5}
  .dbp-point[data-cp="start"] .dbp-plabel{color:#2C82B5}
  .dbp-point[data-cp="1"] .dbp-dot{background:#C43D74}
  .dbp-point[data-cp="1"] .dbp-plabel{color:#C43D74}
  .dbp-point[data-cp="2"] .dbp-dot{background:#D4622E}
  .dbp-point[data-cp="2"] .dbp-plabel{color:#D4622E}
  .dbp-point[data-cp="3"] .dbp-dot{background:#A16207}
  .dbp-point[data-cp="3"] .dbp-plabel{color:#A16207}
  .dbp-point[data-cp="4"] .dbp-dot{background:#6B8A28}
  .dbp-point[data-cp="4"] .dbp-plabel{color:#6B8A28}
  .dbp-point[data-cp="5"] .dbp-dot{background:#2F8F52}
  .dbp-point[data-cp="5"] .dbp-plabel{color:#2F8F52}
  .dbp-point[data-cp="6"] .dbp-dot{background:#1F8478}
  .dbp-point[data-cp="6"] .dbp-plabel{color:#1F8478}
  .dbp-point[data-cp="7"] .dbp-dot{background:#0E7FA3}
  .dbp-point[data-cp="7"] .dbp-plabel{color:#0E7FA3}
  .dbp-point[data-cp="final"] .dbp-dot{background:var(--gbh-navy)}
  .dbp-point[data-cp="final"] .dbp-plabel{color:var(--gbh-navy)}
  .dbp-connector{background:#9FB0B8}
}

@media (max-width:900px){
  .dbp-body{flex-direction:column;gap:28px}
  .dbp-progression{flex:none;width:100%;padding-left:0;border-left:0;padding-top:22px;border-top:1px solid var(--gbh-line-strong)}
  .dbp-rail{flex-direction:row;flex-wrap:wrap;column-gap:18px;row-gap:10px}
  .dbp-connector{display:none}
  .dbp-plabel{font-size:10px}
}
@media (max-width:575px){
  .dbp-panel{padding:32px 24px}
  .dbp-line{font-size:14.5px}
}

/* ---------- why gbh: orchestration system (2026-08-27 final structural pass) ----------
   Replaces the hub-and-spoke diagram entirely — GBH at top, the four specialist
   functions it coordinates, one accountable operating model, one outcome, connected by
   straight vertical rules only. Normal document flow (no absolute positioning, no SVG
   spokes), which is also why the old mobile collision-avoidance logic and its fallback
   caption are gone: there's nothing left that CAN collide. */
.orchestration{position:relative;z-index:1;width:100%;padding:40px 32px;text-align:center}
.orch-gbh{display:inline-block;font-family:var(--tj-ff-heading);font-size:20px;font-weight:600;letter-spacing:.02em;color:var(--gbh-on-dark);padding-bottom:10px;border-bottom:1.5px solid rgba(248,245,239,.3)}
.orch-line{width:1px;height:26px;margin:0 auto;background:rgba(248,245,239,.22)}
.orch-line.accent{background:var(--gbh-crit);height:30px}
/* two stacked rows (2+3) rather than one line — "Marketing & Social Media" doesn't
   fit gracefully alongside four other labels on one line without shrinking the type
   or wrapping awkwardly mid-label. */
.orch-row{display:flex;justify-content:center;flex-wrap:wrap;gap:10px 26px;margin:7px 0}
.orch-row span{font-family:var(--tj-ff-body);font-size:12.5px;font-weight:600;letter-spacing:.03em;color:rgba(248,245,239,.82);white-space:nowrap}
.orch-model{font-family:var(--tj-ff-body);font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:#8FA0AB;line-height:1.5;margin:10px 0}
.orch-outcome{font-family:var(--tj-ff-heading);font-size:24px;font-weight:600;color:var(--gbh-on-dark);margin-top:6px}
/* "running." one-time reveal (2026-08-29): default state is fully visible (the
   correct JS-failure fallback) — gbh-app.js is the only thing that ever adds
   .pre-reveal, and only right before it triggers the reveal transition, so a
   script failure simply leaves the complete static text showing, never stuck
   hidden. No looping, no ellipsis — a single soft fade + lift into place. */
.orch-running-word{display:inline-block;opacity:1;transform:translateY(0);transition:opacity .7s ease,transform .7s ease}
.orch-running-word.pre-reveal{opacity:0;transform:translateY(6px)}
@media (prefers-reduced-motion:reduce){
  .orch-running-word{transition:none}
  .orch-running-word.pre-reveal{opacity:1;transform:translateY(0)}
}
/* mobile: the four function names wrap to 2 lines at this width (confirmed via
   measurement — content ran 23px taller than the 1:1 frame, which would have clipped
   under the frame's overflow:hidden). Trimmed padding/line-height/row-gap to fit
   comfortably instead of changing the frame's proportions. */
@media (max-width:575px){
  .orchestration{padding:22px 18px}
  .orch-gbh{font-size:18px;padding-bottom:8px}
  .orch-line{height:18px}
  .orch-line.accent{height:20px}
  .orch-row{gap:14px 20px;margin:10px 0}
  .orch-model{margin:8px 0}
  .orch-outcome{font-size:19px;margin-top:4px}
}

/* large editorial pull-quote — deliberately strips Bexon's default boxed-blockquote
   treatment (bright-blue border + pale-blue fill + bright-blue quote glyph from
   main.css) in favor of open typography, consistent with the "no cards" direction.
   The ::before icon-glyph (main.css's own bexon-icons quotation mark, ~40px) was only
   recolored in an earlier pass, not removed — still visibly a decorative quote symbol
   on the dark section even at low opacity. Removed outright now (consolidated pass). */
.pull-quote{max-width:900px;margin:0 auto;text-align:center}
.pull-quote blockquote{font-family:var(--tj-ff-heading);font-size:clamp(24px,3.2vw,38px);line-height:1.35;color:var(--gbh-navy);font-weight:500;margin:0;padding:0;background:none;border:0;border-radius:0}
.pull-quote blockquote::before{content:none}
.pull-quote cite{display:block;margin-top:22px;font-family:var(--tj-ff-body);font-style:normal;font-size:11.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--gbh-gold-deep)}

/* ---------- utility ---------- */
.protobadge{display:inline-block;font-family:var(--tj-ff-body);font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#8C6A2F;background:#F1E6CD;padding:3px 9px;border-radius:100px}
