/* ==========================================================================
   Graintree Product Pages
   --------------------------------------------------------------------------
   Every visual decision lives in the token block below. When the design
   lands, the expected change is: edit :root, swap the image sizes, adjust a
   handful of spacing values. Structure and behaviour do not move.

   Class prefix is gt- throughout so nothing collides with the theme.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   Colours sampled directly from the designer's 2x Figma exports, 27 Aug 2026.
   Geometry measured off the same files. Type sizes are measured from ink
   extents and are accurate to about 2px; confirm against the designer's file on handoff.
   -------------------------------------------------------------------------- */
:root {
  /* ---- colour: exact, sampled ---- */
  --gt-navy:    #122B34;  /* hero band, footer                      */
  --gt-navy-2:  #263846;  /* underwriting band, accordion bars, ink */
  --gt-paper:   #F8F4F1;  /* page background                        */
  --gt-panel:   #F5F5F5;  /* open accordion panel, card fill        */
  --gt-card:    #FFFFFF;  /* underwriting + audience cards          */
  --gt-tile:    #BDC6C4;  /* Why Graintree tiles. Sampled from the final desktop
                             export: mist tiles on a #F5F5F5 section. All four the
                             same colour, confirmed 1 Sep. */
  --gt-sage:    #A7A499;  /* mid-page CTA band                      */
  --gt-mist:    #BDC6C4;  /* Built Around Relationships band        */
  --gt-bronze:  #7E6D59;  /* closing CTA band                       */

  --gt-ink:     #263846;
  --gt-on-dark: #F8F4F1;
  --gt-line:    #263846;  /* hairlines are the ink colour, not a grey */

  /* legacy aliases so older rules keep resolving */
  --gt-teal: var(--gt-navy);
  --gt-teal-2: var(--gt-navy-2);
  --gt-paper-2: var(--gt-panel);
  --gt-slate: var(--gt-navy-2);
  --gt-slate-lt: var(--gt-sage);
  --gt-muted: var(--gt-ink);

  /* ---- type ---- */
  /* The theme registers the brand faces under generic @font-face names in
     landing-page-theme/style.css, not under their real names:
       MyCustomFont  = TYSerif-D        (The Youngest Serif)
       MyCustomFont2 = Aktiv Grotesk    (regular / bold / italic)
       MyCustomFont3 = SweetSansProBold (declared at weight 400)
     The alias has to come first or the whole page silently falls back to
     Georgia and a system sans. Real names are kept after it so this still
     works if the theme is ever tidied up. */
  --gt-serif: "MyCustomFont", "The Youngest Serif", Georgia, "Times New Roman", serif;
  --gt-sans:  "MyCustomFont2", "Aktiv Grotesk", -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --gt-label: "MyCustomFont3", "Sweet Sans Pro", var(--gt-sans);

  /* Type is FIXED, not fluid. The 1440 and 1024 exports carry byte-identical
     type: eyebrow 182px wide, h2 602.5px, lede lines 705 / 727.5 / 696, tiles
     715.5px. The design does not scale between those two frames, it re-centres.
     Sizes below are solved from the exports: the string is measured in the
     export, the same string is measured live at a known size, and the ratio
     gives the size. That is far more reliable than reading cap heights.
     The mobile step is at 600px, matching the theme's own breakpoint. */
  --gt-h1:      76px;   --gt-h1-lh:   82.2px;
  /* KENDRA'S TYPESCALE, sent 2 Sep 18:34. This is the authority now.
     The designer's first email said H2 36/38.2; the correction explains why: the designer's Figma
     scale had a "Display" row at the top that has no HTML equivalent, so every
     name was off by one. 36/38.2 is H3.
     It also validates the string-measurement method: every solved value came
     in within about a pixel of the designer's spec. */
  --gt-h2:      52px;   --gt-h2-lh:   53.2px;
  --gt-h3:      36px;   --gt-h3-lh:   38.2px;
  --gt-h4:      24px;   --gt-h4-lh:   38.2px;
  --gt-body-lg: 19px;                          /* section and hero ledes */
  --gt-body:    16px;   --gt-body-lh: 25.5px;  /* Body 1 */
  --gt-caption: 14px;   --gt-caption-lh: 19.9px;
  --gt-small:   16px;
  --gt-lbl:     16px;   /* Eyebrow 1. Eyebrow 2 is 13px, used below 600 */
  --gt-lbl-ls:  .2em;
  --gt-base:    17px;

  /* ---- geometry: measured ---- */
  /* The theme's header is `.top-band { padding-left: 5vw }`, flush left with
     no max-width. Matching it is what puts our copy on the same line as the
     logo, which is what the design shows and what every other page does.
     At 1440 this gives a 1296px content width against the export's 1320. */
  --gt-max:     none;
  --gt-gut:     max(20px, 5vw);

  /* The HERO's left edge, which is not the body gutter. Julian, 9 Sep: "in all
     the pages the main heading aligns left with the logo except for Residential
     Lending".

     He is right, and the site has a convention we were not following. Measured
     on /about-us/ at 1512:

         logo                        left 56.0
         hero heading "About"        left 56.0   <- flush with the logo
         body headings, Our Mission  left 75.6   <- the 5vw gutter

     So the hero heading aligns with the logo and everything below it sits on
     the wider gutter. Our hero used --gt-gut for both, which put the h1 at
     75.6 and 19.6px right of the logo. The gap grows with the window, because
     56px is fixed and 5vw is not: 40px out at 1920.

     56px because that is the horizontal padding in the designer's header CSS
     (`.top-band { padding: 16px 56px }`, 24px 16px on mobile). THIS VALUE HAS
     TO TRACK THAT ONE. If the header padding changes, change this with it or
     the hero drifts off the logo again. */
  --gt-edge: 56px;
  --gt-band:    72px;   /* Designer, 2 Sep: 72 top and bottom on all components */
  --gt-row-h:   70px;     /* accordion bar height, measured 69–70 */
  --gt-btn-h:   47px;     /* measured 286 x 47 */
  --gt-btn-px:  32px;
  --gt-radius:  2px;      /* Designer, 4 Sep: 2px on all buttons. Only the
                             buttons use this token; every other corner in
                             the design is square or has its own value. */
  --gt-gap:     24px;
  --gt-nav-h:   58px;

  /* Card width lives here because the row's side padding is derived from it:
     the padding has to be half the row minus half a card, or the first and
     last card can never reach the centre. */
  --gt-uwc-w:   clamp(260px, 29vw, 428px);

  /* ONE GRADIENT FOR EVERY WIDTH, anchored in px rather than percentages.
     Julian, 5 Sep: he wants it to reach 0 at the right edge, and it does.
     The percentage version could not: the copy takes a bigger share of a
     narrow window, so a 45% midpoint left the text sitting in the faded part.
     Measured with the last stop at 0: the h1 fell to 1.59:1 at 1024 and the
     lede to 2.49:1, both far under AA.
     Anchoring the midpoint at 1000px instead means the strong part always
     covers the measure, whatever the window, and the fade happens in the
     right-hand third where no text ever goes. Composited against the real
     photograph at nine widths from 393 to 2560: the h1 never drops below
     8.2:1 and the lede never below 8.4:1. That is better than the three
     separate gradients it replaces, so the tablet and mobile overrides are
     gone too. Re-measure if the photograph is ever swapped.

     SUPERSEDED 8 Sep on the call. The designer asked for a flat overlay at
     40% and no gradient: "instead of a gradient that like 70% of the image is
     darkened, the whole thing is darkened, but only to like 40% opacity", and
     "if we have to darken it more, then we can show Ashley what it looks like
     with a slightly darker opacity". So flat it is, and the number below is
     the one to argue about, not the shape.

     MEASURED ON THE REAL FILE, and 40% does not pass. Compositing the
     photograph Ashley licensed under a flat overlay, headline against
     background, at 393 / 768 / 1024 / 1512 / 1920:

     SHIPPING 45%, Julian's call on 8 Sep. Below is what that costs, measured,
     so the decision is on the record rather than assumed.

     The first pass of this measurement applied 4.5:1 to everything, which was
     wrong. WCAG splits the threshold by type size, and the two pieces of hero
     copy land on opposite sides of it:

         h1    76px regular  ->  LARGE text  ->  3.0:1
         lede  19px regular  ->  normal text ->  4.5:1

     Re-measured against the licensed photograph at six widths, 393 to 2560,
     reporting both the worst pixel and how much of each text area misses:

         overlay    h1 worst   h1 under 3.0    lede worst   lede under 4.5
           40%        2.22        0.75%           2.35          25.7%
           45%        2.52        0.02%           2.63          19.4%
           55%        3.31        0.00%           3.37           3.3%
           66%        4.59        0.00%           4.52           0.0%

     So at 45% THE HEADLINE IS EFFECTIVELY FINE. 0.02% of its area misses 3:1,
     which is a handful of pixels against the brightest part of the sky, not
     something a reader meets. The failure is the LEDE, and it is not marginal:
     about a fifth of that paragraph sits under 4.5:1.

     No type change rescues it. Taking the lede to 24px would make it large
     text at a 3:1 threshold, but 45% only reaches 2.63, so it still misses.
     The two things that would actually fix it at 45%:

       1. Regrade the photograph to 65% brightness or darker. Measured: the
          lede then reaches 4.79:1 at 45%. This is the option that gives the
          designer the light overlay she wanted AND passes.
       2. Back the copy column only, which means a second scrim, which is the
          gradient she asked us to remove.

     Left as a live decision rather than quietly fixed. tools/scrim.py and
     tools/correct.py reproduce all of the above. Re-measure if the photograph
     is ever swapped or regraded. */
  --gt-hero-scrim: linear-gradient(rgba(18,43,52,.45), rgba(18,43,52,.45));

  --gt-ease: cubic-bezier(.4, 0, .2, 1);

  /* Accordion motion. Read by product-page.js, so the pace is a CSS decision
     and the designer can retune it without touching the JavaScript.

     These match the site's existing motion vocabulary rather than a number I
     invented. From the theme, 7 Sep:

       headline-reveal.js   1.6s, GSAP power3.out, 0.18s stagger
       animation.js         CROSSFADE_MS = 1100, ease
       customizer-additional.css, the <details> rule   1s ease

     Everything on this site moves slowly and decelerates. Our first pass ran
     the accordion at .55s on --gt-ease, which is a symmetric in-out curve at
     roughly half the site's duration, and it read as snappy against the rest
     of the page. The .55s came from the anchor-link pace the designer asked
     for on 4 Sep, applied to the accordion by me. She has never actually seen
     this animate, because until v0.4.4 it did not.

     The ease is easeOutQuart, which is the CSS equivalent of the theme's
     power3.out: quick to start, long slow settle. The fade outlasts the height
     by design, so the panel finishes moving before it finishes arriving. */
  --gt-acc-dur:  .8s;
  --gt-acc-fade: 1s;
  --gt-acc-ease: cubic-bezier(.165, .84, .44, 1);

  /* In-page anchor scrolling, read by initSmoothAnchors in product-page.js.
     Julian, 9 Sep: the hero buttons should scroll "aligned with animation
     timing of other items". Same duration as the accordion, and the JS uses
     easeOutQuart, which is the curve --gt-acc-ease approximates. Kept as its
     own token because a long page may want a longer travel than a panel. */
  --gt-scroll-dur: .8s;   /* floor: short hops move at the accordion's pace */
  --gt-scroll-max: 2.2s;  /* ceiling: the full-page trips, #contact included */
}

/* --------------------------------------------------------------------------
   2. SCOPE + RESET
   Only applies inside .gt-page so the rest of the site is untouched.
   -------------------------------------------------------------------------- */
/* SCOPE. .gt-page sits on <body>, so anything scoped to it also restyles the
   theme's header, nav and footer. That is how the site nav lost its serif and
   picked up our body sans. Our own section roots are the correct scope; the
   editor canvas contains only our content, so it can stay broad. */
:is(.gt-hero, .gt-band, .gt-close, .gt-cta-band, .editor-styles-wrapper) {
  color: var(--gt-ink); font-family: var(--gt-sans); font-size: var(--gt-base); line-height: 1.6;
}
/* Scoped to our own sections, not the whole body. .gt-page sits on <body>,
   so a blanket reset here also reaches the theme's header, nav and footer. */
:where(.gt-hero, .gt-band, .gt-close, .gt-cta-band) :is(*, *::before, *::after) { box-sizing: border-box; }
:is(.gt-hero, .gt-band, .gt-close, .gt-cta-band, .editor-styles-wrapper) img { max-width: 100%; height: auto; display: block; }
:is(.gt-hero, .gt-band, .gt-close, .gt-cta-band, .editor-styles-wrapper) :is(h1, h2, h3, h4) {
  font-family: var(--gt-serif); font-weight: 400; margin: 0; letter-spacing: -.005em;
  /* explicit: the theme sets a bare `h2 { color: #000 }`, which beats the
     colour inherited from .gt-page */
  color: var(--gt-ink);
}
:is(.gt-hero, .gt-band, .gt-close, .gt-cta-band, .editor-styles-wrapper) p { margin: 0; }
:is(.gt-page, .editor-styles-wrapper) section { scroll-margin-top: calc(var(--gt-nav-h) + 10px); }

/* This theme is classic, with no theme.json, so WordPress serialises every
   core/group as
     <div class="wp-block-group"><div class="wp-block-group__inner-container">
   and the editor bakes that wrapper into the post content on save. Without
   this rule every grid and flex container below sees exactly one child and
   collapses: the four tiles stack, the card row becomes one column, the
   audience cards go full width.
   display:contents takes the wrapper out of layout while leaving it in the
   DOM. It carries no background, border or padding of its own, so nothing is
   lost. Selectors below use descendant combinators rather than `>` so the
   same CSS is correct whether the wrapper is there or not. */
:where(.gt-hero, .gt-band, .gt-close, .gt-cta-band) .wp-block-group__inner-container { display: contents; }

/* THE CLIPPED LOGO AND THE 18px GAP WERE ONE THEME RULE. Found 4 Sep, in
   themes/landing-page-theme/customizer-additional.css:

       body:not(.home) .wp-block-group.top-band { padding-bottom: 0vw !important; }

   Every page except the home page has its header band's bottom padding zeroed.
   The band then sizes to the nav row alone (76.4px), while the site logo is
   absolutely positioned and runs to 94.3px, so it hung 18px out of the band on
   every inner page. That overhang WAS the "18px gap": measured band bottom
   76.4, hero top 94.4, and the body's cream showing through between them.

   Giving the padding back fixes both at once. Measured after: 36px of clear
   navy below the logo and a gap of exactly 0. The navy cover strip that used to
   paint over the gap is gone with it, since there is no longer a gap to cover.

   The selector has to match the theme's specificity to beat its !important:
   `body:not(.home) .wp-block-group.top-band` is (0,3,1), so ours is too and
   wins on order, this stylesheet being the later one. Delete both rules from
   the theme file and this can go.

   SUPERSEDED 8 Sep, by the designer's own Customizer CSS:

       .custom-logo { width: 12em }
       body.gt-page .wp-block-group.top-band { padding: 16px 56px !important }

   Identical selector to ours, therefore identical specificity, and the
   Customizer prints after this stylesheet, so her shorthand wins and our
   padding-bottom never applies. That is fine, because it is no longer needed:
   measured on dev 8 Sep, band 80px tall, logo 192 x 46 sitting at top 16 and
   bottom 62, entirely inside the band. **The clipping is gone because the logo
   is smaller now, not because of the padding.** Our rule is removed rather than
   left in to look like it is doing something.

   THE DEPENDENCY, worth knowing: the two halves of her block travel together.
   Remove `.custom-logo { width: 12em }` without also restoring padding and the
   275px logo overhangs an 80px band again. */

/* The designer, 4 Sep: "cannot tell what is producing that cream spacing
   between the brown container and the footer?". It is this page's Spectra block
   custom CSS, `footer { position: relative !important; bottom: -20px !important }`.
   The footer is pushed down 20px and the body's cream shows through behind it.
   (Deleted by accident in v0.4.1 along with the top-band block, and the gap
   came straight back. Restored in v0.4.2.) */
.gt-page footer { bottom: auto !important; }

/* --------------------------------------------------------------------------
   FOOTER LICENSING DISCLOSURE. Ashley, 9 Sep: required by compliance, this
   page only for now.

   The markup lives in the theme's footer.php behind a `gtpp_is_product_page()`
   guard, not here. A legal notice has to render server-side with the page, so
   it cannot be injected by script, and putting it INSIDE <footer> means it
   inherits the footer's own colour and centring rather than restating them.

   FOUR STATEMENTS, compliance's string verbatim. It was briefly trimmed to two
   on 9 Sep to avoid repeating the address, but Ashley came back the same day:
   the licensed mortgage entity is Graintree Home Lending, LLC, not the
   Graintree, LLC in the copyright line, and it has to appear next to the NMLS
   ID. So the full string is back, and the duplicate is solved at the other end
   instead: footer.php suppresses the older address paragraph on these pages.

   SPECIFICITY IS LOAD-BEARING HERE. The theme has `footer.footer p` at (0,2,1),
   which sets `margin: 0 0 10px` and therefore kills the auto side margins that
   centre this block. `.gt-page .gt-legal` is only (0,2,0) and loses to it: the
   disclosure renders hard against the left edge of the footer. Caught in a
   render at 1024 before it shipped. The selectors below are (0,4,3), which
   clears it with room to spare.

   Measured rather than guessed: at 13px the one-line form is 1075px wide and
   needs a 1115px viewport. The stack breakpoint is 1240px, which leaves about
   125px of headroom for the theme's font rendering differently from the test.

   The 1200px cap is the hairline's width. It sits a little wider than the text
   so the rule frames the block rather than ending flush with the last word.

   No colour and no opacity on the text. Every other line in this footer is
   decoration; this one is a regulatory statement and stays fully legible.
   -------------------------------------------------------------------------- */
body.gt-page footer.footer p.gt-legal {
  margin: 26px auto 0;
  width: auto;
  max-width: 1200px;
  padding: 22px 20px 0;
  font-size: 13px;
  line-height: 1.9;
  color: inherit;
  /* A hairline marks the regulatory block off from the marketing links above
     it. The fallback is the paper tint; where color-mix is supported the rule
     is derived from the footer's own text colour and cannot mismatch. */
  border-top: 1px solid rgba(248, 244, 241, .18);
  border-top: 1px solid color-mix(in srgb, currentColor 22%, transparent);
}
body.gt-page footer.footer .gt-legal-i {
  /* nowrap so a wrap can only ever fall BETWEEN statements, never inside one.
     Without it the line broke mid-phrase at "For licensing information, / go
     to:", which reads like a mistake. */
  display: inline-block;
  white-space: nowrap;
}
body.gt-page footer.footer .gt-legal a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
body.gt-page footer.footer .gt-legal-sep {
  padding-inline: 9px;
  opacity: .45;   /* the separator is decoration, so it may recede */
}

/* Below 1240 the line cannot fit, so it stacks rather than wrapping. Two clean
   states, no middle. Wrapping a pipe-separated line strands a separator at the
   end of a line with nothing after it, which is the thing that reads as broken;
   stacking never can. The pipes are aria-hidden either way, so a screen reader
   gets the same text at every width.

   The URL goes to its own line rather than being left to wrap where it lands.
   On a phone the licensing statement needs two lines whatever happens, so the
   only question is where the break falls, and after the colon is the one place
   it reads as deliberate. Horizontal fit verified down to 320px. */
@media (max-width: 1240px) {
  body.gt-page footer.footer p.gt-legal {
    font-size: 12px;
    line-height: 1.7;
    max-width: 30rem;
    margin-top: 30px;
    /* no side padding of its own here: the footer already pads 20px, and
       doubling it costs 40px of a 393px screen for nothing. */
    padding: 24px 0 0;
  }
  body.gt-page footer.footer .gt-legal-i {
    display: block;
    white-space: normal;
    text-wrap: balance;   /* stops "10017" orphaning onto its own line */
    margin-bottom: 6px;
  }
  body.gt-page footer.footer .gt-legal-i:last-child { margin-bottom: 0; }
  body.gt-page footer.footer .gt-legal-url { display: block; }
  body.gt-page footer.footer .gt-legal-sep { display: none; }
}

/* THEME BUG 7, and the seventh in customizer-additional.css. The mobile menu
   is "not visible or clickable" (designer, 9/7, and Julian's screenshot of the
   open drawer with the hero headline painted straight through it).

   The theme rebuilds the mobile nav as a right-hand drawer:

     @media (max-width: 976px) {
       .wp-block-navigation { position: absolute !important; z-index: 1; }
       .wp-block-navigation__responsive-container.is-menu-open {
         position: fixed !important; right: 0; width: 70vw; max-width: 360px;
         background: rgba(226,222,219,.98) !important;
         z-index: 100000 !important;
       }
     }

   Putting a z-index on the <nav> makes it a stacking context, so the drawer's
   own 100000 is only 100000 *within the nav*, and the nav itself is 1 against
   the rest of the page. Anything on our page above 1 therefore paints over an
   open menu, and takes its clicks with it. We have two such things, both
   deliberate: .gt-hero-copy at 2 and the sticky section nav at 40.

   So this is not a menu bug, it is a stacking bug, and it would hit any page
   with a positioned element on it. Fixed here by raising the nav rather than
   lowering our page, because lowering the page would break the hero's own
   internal layering.

   FIRST ATTEMPT WAS WRONG, and it is worth writing down why, because the
   reasoning looked sound. v0.4.5 raised the <nav>. That could never work: the
   nav is not the element being capped. Walking the real chain on dev, 9 Sep:

     MAIN.wrap                position: relative  z-index: 1   <- context
       DIV.top-band           position: relative  z-index: 2   <- context
         NAV                  position: absolute  z-index: 1   <- context
           .is-menu-open      position: fixed     z-index: 100000
       SECTION.gt-hero
         DIV.gt-hero-copy     position: relative  z-index: 2   <- context

   The contest is not nav versus hero. It is **.top-band (2) versus
   .gt-hero-copy (2)**, two stacking contexts on equal z-index inside
   MAIN.wrap, where equal means source order decides and the hero comes later
   in the document. Everything inside .top-band, the nav's 100000 included,
   is sealed under that 2. Raising the nav moved a number inside a box that
   was already losing.

   So the fix is on .top-band, the outermost capped ancestor. Verified by hit
   test on dev: before, elementFromPoint anywhere inside the open drawer
   returned .gt-hero-copy; after, it returns the drawer and its links.

   60 at rest clears the sticky section nav (40) so the hamburger stays
   clickable while scrolled. 100000 while open. WordPress puts .has-modal-open
   on <body> itself, so no :has() and no browser caveat.

   ---------------------------------------------------------------------------
   9 Sep, LATER: THE SAME BUG HAS A DESKTOP HALF, and the fix above was scoped
   to phones so it never touched it.

   Kendra: "on desktop, when you hover between Professional <li> and Residential
   <li> the submenu disappears."

   It is not a menu bug either. The Products dropdown is
   `position: absolute; top: 100%` on its parent <li>, so it hangs below the
   band and over the hero. `.top-band` is still z-index 2 out here, and
   `.gt-hero-copy` is also 2, and the hero comes later in the document. Exactly
   the contest above, just at a different width.

   So the hero paints over the dropdown and, more to the point, TAKES ITS
   POINTER EVENTS. Core opens the submenu with
   `.has-child:not(.open-on-click):hover`, a plain CSS hover on the parent <li>.
   The moment the pointer crosses into the covered region it is hovering the
   hero, the <li> is no longer hovered, and the submenu closes. Moving between
   two items in the list is simply when that happens.

   Reproduced from the stacking chain rather than guessed: with .top-band at 2,
   `elementFromPoint` at the centre of every dropdown item returns
   `.gt-hero-copy`; at 60 it returns the items themselves. Same hit test that
   settled the mobile half.

   The fix is therefore the same fix, and it should never have been inside a
   media query: the header has to outrank page content at every width. Moved
   out. Nothing else about the rule changes.

   SCOPE, and it matters. `.gt-hero-copy` is OURS, so this cures the three
   product pages. If the dropdown misbehaves on a page we did not build, the
   culprit there is a different positioned element and the fix belongs sitewide
   in the Customizer, next to the header block:

       .wp-block-group.top-band { position: relative; z-index: 60; }

   Ask Kendra to check one non-product page before adding that, so a sitewide
   z-index change is made on evidence rather than on suspicion. */
body.gt-page .wp-block-group.top-band { z-index: 60; }
body.gt-page.has-modal-open .wp-block-group.top-band { z-index: 100000; }

@media (max-width: 976px) {
  /* Designer, 9/7. The theme sets top: -14px at one breakpoint and -45px at
     another; this is the value she wants against the 16px band padding. */
  body.gt-page button.wp-block-navigation__responsive-container-open {
    top: -7px !important;
  }

  /* Julian, 9 Sep: the two Lending items "are changed to something different
     than the rest of the mobile navigation".

     Measured, and it is not size or font. Every label in the drawer computes
     13px uppercase in the same face. The whole difference is OPACITY: the
     theme fades every item to .4 and lifts only .current-menu-item to 1, so
     on the Residential Lending page that one item reads solid and everything
     else reads ghosted.

     .4 is also a contrast failure, which is the reason to change it rather
     than a preference. The theme's overlay ink is #0d1220 on the drawer's
     rgba(226,222,219,.98): at .4 that composites to 2.49:1, well under the
     4.5:1 these 13px labels need. .7 measures 6.09:1.

     So this lifts the resting state to .7 and leaves the current-page item at
     1. Navigation stays legible, the current page is still marked, and the
     gap between the two stops looking like a styling bug. */
  body.gt-page .wp-block-navigation__responsive-container.is-menu-open
    .wp-block-navigation-item__content { opacity: .7; }
  body.gt-page .wp-block-navigation__responsive-container.is-menu-open
    .wp-block-navigation-item.current-menu-item .wp-block-navigation-item__content { opacity: 1; }
}

.gt-wrap { max-width: var(--gt-max); margin-inline: auto; padding-inline: var(--gt-gut); }
/* The old rule capped the box at 1320 and then padded INSIDE it, so the
   content was 1224 wide starting at 108 on a 1440 frame. The export puts it
   at 1320 wide starting at 64. Everything on the page inherited that 44px
   error, which is most of what "spacing is off" was. */
/* distance from the viewport edge to the container edge, for full-bleed rows */
/* --gt-max is none now, so the old bleed calc resolves to NaN. The gutter is
   the whole distance to the edge. */
:root { --gt-bleed: var(--gt-gut); }

:is(.gt-hero, .gt-band, .gt-close, .gt-cta-band, .editor-styles-wrapper) .gt-eyebrow,
.gt-eyebrow {
  /* 15px, not 11px: the export's "WHY GRAINTREE" is 182px wide */
  /* MyCustomFont3 is the Bold cut declared at weight 400. Asking for 700
     makes the browser synthesise bold on top of it, which smears. */
  /* !important answers the theme's own: landing-page-theme/style.css has
     `pre, p { font-family: MyCustomFont2, sans-serif !important }`. Body
     copy wants that face anyway, so this is the only place it has to be
     overridden, and specificity alone cannot do it. */
  font-family: var(--gt-label) !important; font-size: var(--gt-lbl); font-weight: 400;
  letter-spacing: var(--gt-lbl-ls);
  text-transform: uppercase; color: var(--gt-slate); margin: 0 0 16px;
}

/* generic band */
.gt-band { padding-block: var(--gt-band); background: var(--gt-paper); }
.gt-band--alt { background: var(--gt-paper-2); }

/* Band colours, in page order. These MUST come after .gt-band: same specificity,
   so source order decides. Putting them earlier silently loses to the base rule. */
.gt-band--dark   { background: var(--gt-navy-2); color: var(--gt-on-dark); }
.gt-band--sage   { background: var(--gt-sage); }
.gt-band--mist   { background: var(--gt-mist); }
.gt-band--bronze { background: var(--gt-bronze); color: var(--gt-on-dark); }
.gt-band--white  { background: #FFFFFF; }

/* text on the dark and bronze bands */
/* doubled class so these beat .gt-sechead p, which is also two levels deep */
:is(.gt-band--dark, .gt-band--bronze).gt-band :is(h1, h2, h3, h4, p, li) { color: var(--gt-on-dark); }
:is(.gt-band--dark, .gt-band--bronze).gt-band .gt-sechead p:not(.gt-eyebrow) { color: rgba(248,244,241,.82); }
:is(.gt-band--dark, .gt-band--bronze).gt-band .gt-eyebrow { color: rgba(248,244,241,.72); }
/* cards sitting on a dark band keep their own ink */
:is(.gt-band--dark, .gt-band--bronze).gt-band :is(.gt-uwc, .gt-audc) :is(h1,h2,h3,h4,p) { color: var(--gt-ink); }
.gt-sechead { max-width: 56ch; margin-bottom: 64px; }
/* the dark band's lede is set wider than the rest, as drawn */
.gt-band--dark .gt-sechead { max-width: 820px; }
.gt-sechead h2 { font-size: var(--gt-h2); line-height: var(--gt-h2-lh); }
.gt-sechead p:not(.gt-eyebrow) {
  color: var(--gt-muted); margin-top: 23px;
  font-size: var(--gt-body-lg); line-height: var(--gt-body-lh);
}

/* --------------------------------------------------------------------------
   3. MEDIA SLOTS
   A media container shows a brand gradient until an Image block is placed
   inside it. Inserting the image is the only action needed; it covers the
   gradient automatically. Slots: .gt-hero-media, .gt-split-media, .gt-cat.
   -------------------------------------------------------------------------- */
.gt-media, .gt-hero-media, .gt-split-media, .gt-cat {
  background-image:
    linear-gradient(115deg, rgba(18,42,51,.55), rgba(18,42,51,.05)),
    linear-gradient(200deg, #2C5566 0%, #3E6E7E 38%, #6E8E96 70%, #A9B9BC 100%);
  background-size: cover;
}
/* Any image placed inside a media slot fills it.
 *
 * DESCENDANT, NOT CHILD. These were `> figure` and it silently did nothing the
 * moment a real photograph went in, because WordPress serialises every
 * core/group with a .wp-block-group__inner-container wrapper:
 *
 *   .gt-hero-media > .wp-block-group__inner-container > figure > img
 *
 * `display: contents` on that wrapper changes how it renders, not how selectors
 * match, so `.gt-hero-media > figure` never matched. The figure stayed static
 * with height:auto, so the image sized itself off its own aspect ratio instead
 * of filling the band: too tall at 1512 (764 against a 656 hero, overflowing)
 * and too short at 1108 (560 against a 677 hero, leaving the fallback gradient
 * showing as a blue strip under the photograph). Same wrapper, same trap as the
 * collapsed grids on 1 Sep. */
.gt-hero-media figure,
.gt-split-media figure,
.gt-cat figure {
  position: absolute; inset: 0; margin: 0; width: 100%; height: 100%; z-index: 0;
}
.gt-hero-media figure img,
.gt-split-media figure img,
.gt-cat figure img { width: 100%; height: 100%; object-fit: cover; }
/* Bias the hero crop downwards. The hero is between 2.3:1 and 3.4:1 depending
   on the window, against a 1.98:1 photograph, so a centred cover crop takes
   the slice out of the middle: at 2560 x 760 that leaves the houses cut off at
   the rooflines. 78% keeps them framed at every width and only gives up sky at
   the widest. Nothing below 600 is affected, where the crop is width-bound. */
.gt-hero--full .gt-hero-media figure img { object-position: 50% 78%; }
.gt-cat figure { z-index: -2; }

/* --------------------------------------------------------------------------
   4. HERO
   Two variants. gt-hero--full is the approved one (31 Aug): photography fills
   the section, copy sits over it behind a scrim. gt-hero--split keeps the
   earlier side-by-side treatment.
   -------------------------------------------------------------------------- */
.gt-hero { background: var(--gt-navy); color: var(--gt-on-dark); position: relative; }
.gt-hero :is(h1, h2) { color: var(--gt-on-dark); }

/* ---- full-bleed ---- */
.gt-hero--full { display: grid; align-items: center; min-height: clamp(520px, 72vh, 760px); overflow: hidden; }
.gt-hero--full .gt-hero-media {
  position: absolute; inset: 0; z-index: 0; min-height: 0;
}
/* scrim: keeps the headline legible whatever photograph is used.
   Deepen this rather than editing markup if a very light image is chosen. */
.gt-hero--full::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: var(--gt-hero-scrim);
}
.gt-hero--full .gt-hero-copy {
  position: relative; z-index: 2; padding-block: clamp(56px, 8vw, 110px);
  /* Hero aligns to the logo, not the body gutter. See --gt-edge. */
  padding-inline: var(--gt-edge);
  /* width:100% is load-bearing. .gt-wrap carries margin-inline:auto, and an
     auto margin on a GRID item makes it size to its content instead of
     stretching. The hero was collapsing to the width of the h1 (17ch, about
     776px at 1920) and centring there, so the copy sat mid-page while every
     other section lined up on the 1320 container. Only shows above 1320. */
  width: 100%;
}
.gt-hero--full h1 {
  font-size: var(--gt-h1); line-height: var(--gt-h1-lh);
  margin: 0 0 30px;
  /* 850px, not 17ch. ch is the width of the "0" glyph, which for this serif
     made 17ch about 774px at 76px type: narrower than the 790.5px line 2
     needs in the export, so the headline broke to three lines instead of two.
     The window that keeps the designer's break after "built" is roughly 813 to 875:
     wide enough for "for real-world borrowers", too narrow for "built for"
     to pull up. */
  max-width: 850px;
}
.gt-hero--full .gt-hero-lede {
  font-size: var(--gt-body-lg); line-height: var(--gt-body-lh);
  color: rgba(248,244,241,.92); margin: 0;
  /* 770px, not 52ch. Designer, 3 Sep: "the space for text below main title is
     much wider, close to the width of the title". 52ch measured about 570px
     live, which broke the lede to four lines. The export's three lines run
     722.5 / 739 / 334 wide, so the container has to be at least 741 and less
     than about 798, or "residential" pulls up to line 1 and "equity" to
     line 2. 770 sits in the middle of that window. */
  max-width: 770px;
}
.gt-hero-rule {
  /* SOMETHING ON THIS SITE HIDES EVERY <hr>. Verified in the browser: a bare
     <hr> with no classes, created at runtime and dropped into the hero, also
     computes display:none, while a <div> carrying the same classes renders.
     It is not ours: in the plugin's own preview, with only this stylesheet
     loaded, the rule draws at full width. It is also not findable through
     CSSOM: no rule in document.styleSheets, no @import, no adoptedStyleSheets
     and no inline style matches. Logged for the theme audit.
     Two classes plus !important so this wins whatever it is fighting.
     core/separator also ships its own width, hence the 100%.

     MARGIN IS !important FOR THE SAME REASON. Designer, 3 Sep: "the buttons in
     the hero stuck to the line". Measured on dev at 1512: the rule sat 4.25px
     under the lede and 0.75px above the buttons, so BOTH margins were being
     zeroed, not just shrunk. Whatever hides every <hr> on this site is also
     forcing its margins to 0 with !important, which is why a plain .gt-hero-rule
     declaration lost. Remove these !importants once the theme rule is found.
     Export: 49.5px from the lede's last ink to the rule, 67.5px from the rule
     to the top of the button boxes. */
  display: block !important;
  width: 100%; max-width: none; height: 0;
  margin: 49px 0 68px !important;
  border: 0; border-top: 1px solid rgba(248,244,241,.45);
  visibility: visible !important;
}

/* ---- split (kept, not currently used) ---- */
.gt-hero--split .gt-hero-grid { display: grid; grid-template-columns: 1.05fr .95fr; align-items: stretch; }
.gt-hero--split .gt-hero-copy { padding: clamp(46px,6vw,86px) clamp(20px,4vw,60px) clamp(56px,7vw,96px) var(--gt-gut); }
.gt-hero--split h1 { font-size: clamp(38px, 5.4vw, 68px); line-height: 1.04; margin: 0 0 20px; }
.gt-hero--split .gt-hero-lede { font-size: clamp(16px,1.5vw,19px); color: rgba(248,244,241,.8); max-width: 44ch; margin-bottom: 32px; }
.gt-hero--split .gt-hero-media { position: relative; min-height: 380px; overflow: hidden; }

/* --------------------------------------------------------------------------
   5. STAT STRIP
   -------------------------------------------------------------------------- */
/* gutter lives on the section, not the grid, so the hairline gaps do not
   bleed into the page margin */
.gt-stats { background: var(--gt-teal-2); color: #fff; padding-inline: var(--gt-gut); }
.gt-stats-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1px; background: rgba(255,255,255,.14);
}
.gt-stat { background: var(--gt-teal-2); padding: 26px 4px 26px 0; }
.gt-stat b, .gt-stat strong {
  display: block; font-family: var(--gt-serif); font-weight: 400;
  font-size: clamp(28px, 3vw, 40px); line-height: 1; margin-bottom: 8px;
}
.gt-stat p, .gt-stat span {
  font-family: var(--gt-sans); font-size: 12.5px; letter-spacing: .06em; color: rgba(255,255,255,.72);
}

/* --------------------------------------------------------------------------
   6. PILLARS
   -------------------------------------------------------------------------- */
.gt-pillars {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  border-top: 1px solid var(--gt-line);
}
.gt-pill {
  border-bottom: 1px solid var(--gt-line); border-right: 1px solid var(--gt-line);
  padding: 26px 26px 30px;
}
.gt-pill:last-child { border-right: 0; }

/* Tile treatment. Ashley asked for the tiles to read distinctly against the
   cream section. --gt-tile is the single swap point once Graintree and the designer settle
   on the fill; it defaults to white. */
.gt-pillars--tiles {
  border-top: 0; gap: 16px;
  grid-template-columns: repeat(2, 1fr);   /* 2 x 2 in the final design, not 4 across */
  max-width: 716px; margin-inline: auto;   /* measured 350px + 16 gap + 350px */
}
.gt-pillars--tiles .gt-pill {
  background: var(--gt-tile); border: 1px solid var(--gt-line);
  /* measured: 350 x 334 with 70 top, 26 sides, 66 bottom */
  padding: 70px 26px 66px; text-align: center;
}
.gt-pillars--tiles .gt-pill p:first-child { display: none; }
.gt-pillars--tiles .gt-pill {
  transition: transform .25s var(--gt-ease), box-shadow .25s var(--gt-ease);
}
.gt-pillars--tiles .gt-pill:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 24px rgba(38, 56, 70, .16);
}
@media (prefers-reduced-motion: reduce) { .gt-pillars--tiles .gt-pill:hover { transform: none; } }
@media (hover: none) { .gt-pillars--tiles .gt-pill:hover { transform: none; box-shadow: none; } }
.gt-pillars--tiles .gt-pill h3 { font-size: var(--gt-h3); line-height: var(--gt-h3-lh); margin-bottom: 24px; }

/* Tile icons. The designer's icon set, shipped with the plugin. Same convention as
   the card icons below: the icon is chosen by a class in the block sidebar's
   "Additional CSS class(es)" field, so no SVG lands in the editor.
     gt-pico--service   room service bell   High-Touch Service
     gt-pico--speed     fast-forward        Rapid Momentum
     gt-pico--chat      chat bubbles        Responsiveness
     gt-pico--compass   compass             Solutions Driven
   A tile with no gt-pico-- class simply has no icon, which is a valid look. */
.gt-pill[class*="gt-pico--"]::before {
  content: ''; display: block; width: 46px; height: 46px; margin: 0 auto 30px;
  background-repeat: no-repeat; background-position: center; background-size: contain;
}
.gt-pico--service::before { background-image: url('../img/ico-service.svg'); }
.gt-pico--speed::before   { background-image: url('../img/ico-speed.svg'); }
.gt-pico--chat::before    { background-image: url('../img/ico-chat.svg'); }
.gt-pico--compass::before { background-image: url('../img/ico-compass.svg'); }
.gt-pillars--tiles .gt-pill p { font-size: var(--gt-body); line-height: var(--gt-body-lh); color: var(--gt-ink); }
.gt-pill p:first-child {
  font-family: var(--gt-serif); font-size: 34px; color: var(--gt-slate-lt);
  line-height: 1; margin-bottom: 14px;
}
.gt-pill h3 { font-size: 20px; margin-bottom: 6px; }
.gt-pill p { font-size: 15px; color: var(--gt-muted); line-height: 1.5; }

/* --------------------------------------------------------------------------
   7. UNDERWRITING TILES
   -------------------------------------------------------------------------- */
.gt-uw { display: grid; grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); gap: 10px; }

/* Swipeable card row. Cards bleed past the container on both sides, matching
   the design. Autoplay is deliberately not implemented: pause-on-hover does
   nothing on touch, so autoplay needs a visible pause control first. */
#documentation, .gt-band:has(.gt-uw--row) { overflow-x: clip; }
.gt-uw--row {
  display: flex; grid-template-columns: none; gap: 34px;
  align-items: center;                       /* lets the centred card stand taller */
  /* No scroll-snap. Centre alignment could never place the first or last
     card at the snapport centre, and every workaround fought the snap engine
     for control of the scroll position. Free scrolling with clamped arrow
     steps is predictable, and .is-active is computed from position anyway. */
  overflow-x: auto;
  /* The row spans the viewport: its containing block is centred, so 50% of it
     and 50vw share a centre line and this puts its edges at 0 and 100vw.
     The side padding is then half the viewport minus half a card, which is
     exactly the room the first and last card need to sit on the centre line.
     With a smaller padding the end cards are visible but can never become the
     centred one, which is the state that carries the tree mark. */
  padding-inline: calc(50vw - var(--gt-uwc-w) / 2); padding-block: 4px 28px;
  margin-inline: calc(50% - 50vw);
  /* Pinned so the section does not breathe while a card grows or shrinks.
     Without it the row height tracks the tallest card, and mid-transition
     both cards are between sizes, so the whole page nudges. */
  min-height: calc(528px + 32px);   /* active card + padding-block. At 556 the
                                       row still grew 4px on every slide. */
  /* Designer, 2 Sep: hide the horizontal scrollbar. The arrows and swipe are
     the affordance; the bar was appearing on scroll and on every arrow click. */
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  /* focusable so a keyboard can reach the scroller itself, see product-page.js */
  scroll-padding-inline: var(--gt-gut);
}
.gt-uw--row .gt-uwc {
  flex: 0 0 var(--gt-uwc-w);
  min-height: 428px; display: flex; flex-direction: column;
  padding: 26px; border: 0; border-radius: 14px;
  transition: min-height .25s var(--gt-ease), transform .2s;
}
/* The card nearest the centre of the row is the snapped one, so emphasising it
   is honest: it is the card the control acts on. product-page.js sets the
   class; without JS every card simply keeps the base height. */
.gt-uw--row .gt-uwc.is-active { min-height: 528px; }
@media (prefers-reduced-motion: reduce) { .gt-uw--row .gt-uwc { transition: none; } }

/* Tree mark, top right, at its drawn size. Decorative, so it is a background
   rather than an <img>: nothing for a screen reader to announce and nothing
   in the editor to delete by accident. */
/* Always in the DOM at zero opacity so it can transition. .55s matches the
   .gt-rv text reveal, which is the rate the designer asked it to match. */
.gt-uw--row .gt-uwc::after {
  content: ''; position: absolute; top: 16px; right: 20px;
  width: 100px; height: 97px; pointer-events: none;
  background: url('../img/tree.svg') no-repeat center/contain;
  opacity: 0; transition: opacity .55s var(--gt-ease);
}
.gt-uw--row .gt-uwc.is-active::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .gt-uw--row .gt-uwc::after { transition: none; }
}
.gt-uw--row .gt-uwc { position: relative; }
.gt-uw--row .gt-uwc h3 { margin-top: auto; font-size: var(--gt-h2); line-height: var(--gt-h2-lh); }
/* hairline between the title and the body copy */
.gt-uw--row .gt-uwc h3::after {
  content: ''; display: block; width: 74%; min-width: 160px; height: 1px;
  background: var(--gt-line); margin: 18px 0 16px;
}
.gt-uw--row .gt-uwc p { font-size: 15px; line-height: 1.5; }
@media (prefers-reduced-motion: no-preference) { .gt-uw--row { scroll-behavior: smooth; } }

/* arrows below the row. Added by product-page.js so they never appear
   without working JS. Same control at every width. */
.gt-uw-nav { display: flex; justify-content: center; gap: 16px; margin-top: 4px; }
.gt-uw-arrow {
  width: 34px; height: 34px; border-radius: 50%;
  border: 0; background: var(--gt-card);
  color: var(--gt-ink); cursor: pointer;
  display: grid; place-items: center; transition: .2s;
}
.gt-uw-arrow:hover:not(:disabled) { background: #fff; transform: scale(1.06); }
.gt-uw-arrow:focus-visible { outline: 2px solid var(--gt-on-dark); outline-offset: 3px; }

/* KEYBOARD FOCUS, EVERYWHERE ELSE.
   Audited 6 Sep: the carousel arrows, the category tiles and both accordion
   summaries had focus styles, but the buttons and the links did not, so the
   most-used controls on the page fell back to the browser default. That is a
   2.4.7 gap, and the default ring is unreliable over a photograph anyway.
   A double ring, paper inside and navy outside, so one half always contrasts
   whatever it lands on: the navy band, the cream band, or the hero image. */
:is(.gt-hero, .gt-band, .gt-close, .gt-cta-band, .editor-styles-wrapper)
  :is(a[href], button, .wp-block-button__link):focus-visible {
  outline: 2px solid var(--gt-paper);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(18,43,52,.9);
  border-radius: 2px;
}
.gt-uw-arrow:disabled { opacity: .38; cursor: default; }
.gt-uw-arrow svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.8; }
@media (prefers-reduced-motion: reduce) { .gt-uw-arrow:hover:not(:disabled) { transform: none; } }

/* the small per-tile icons belong to the grid layout, not to the card
   carousel: the designer's cards carry the tree mark instead */
.gt-uw--row .gt-uwc[class*="gt-ico--"]::before { display: none; }
.gt-uwc {
  background: var(--gt-card); color: var(--gt-ink);
  border: 1px solid var(--gt-line); padding: 20px 20px 22px;
  transition: border-color .2s, transform .2s;
}
.gt-uwc:hover { border-color: var(--gt-slate); transform: translateY(-2px); }

/* Icons are set by a class, not by markup, so there is no SVG in the editor
   for anyone to break. Swap the gt-ico-- class in the block sidebar's
   "Additional CSS class(es)" field to change a tile's icon. */
/* Longhands, not the `background` shorthand: the shorthand would reset
   background-image and this rule out-specifies the per-icon rules below. */
.gt-uwc[class*="gt-ico--"]::before {
  content: ''; display: block; width: 22px; height: 22px; margin-bottom: 12px;
  background-repeat: no-repeat; background-position: center; background-size: contain;
}
.gt-ico--doc::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234E6E7E' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h12l4 4v12H4z'/%3E%3Cpath d='M16 4v4h4'/%3E%3Cpath d='M8 13h8M8 17h5'/%3E%3C/svg%3E"); }
.gt-ico--bank::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234E6E7E' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14'/%3E%3Cpath d='M3 10h18M7 15h4'/%3E%3C/svg%3E"); }
.gt-ico--form::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234E6E7E' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 4h14v16H5z'/%3E%3Cpath d='M9 9h6M9 13h6M9 17h3'/%3E%3C/svg%3E"); }
.gt-ico--chart::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234E6E7E' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 19V5m0 14h16'/%3E%3Cpath d='M8 15l4-5 3 3 4-6'/%3E%3C/svg%3E"); }
.gt-ico--assets::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234E6E7E' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8'/%3E%3Cpath d='M12 8v8M9.5 10.5h5M9.5 13.5h5'/%3E%3C/svg%3E"); }
.gt-ico--house::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234E6E7E' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 21h18'/%3E%3Cpath d='M5 21V10l7-5 7 5v11'/%3E%3Cpath d='M10 21v-6h4v6'/%3E%3C/svg%3E"); }
.gt-uwc h3 { font-size: 18px; margin-bottom: 4px; }
.gt-uwc p { font-size: 14px; color: var(--gt-muted); line-height: 1.45; }

/* --------------------------------------------------------------------------
   8. CATEGORY TILES  (the page's main visual moment)
   -------------------------------------------------------------------------- */
.gt-cats { display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); gap: var(--gt-gap); }
.gt-cat {
  position: relative; min-height: 300px; overflow: hidden; display: flex; flex-direction: column;
  justify-content: flex-end; padding: 26px; color: #fff; text-decoration: none; isolation: isolate;
}
.gt-cat::after {
  content: ''; position: absolute; inset: 0; z-index: -1; transition: background .28s;
  background: linear-gradient(180deg, rgba(18,42,51,.15) 0%, rgba(18,42,51,.55) 45%, rgba(18,42,51,.92) 100%);
}
.gt-cat:hover::after {
  background: linear-gradient(180deg, rgba(18,42,51,.3) 0%, rgba(18,42,51,.7) 45%, rgba(18,42,51,.96) 100%);
}
.gt-cat .gt-cat-n {
  font-family: var(--gt-sans); font-size: 11px; font-weight: 700; letter-spacing: .18em;
  color: rgba(255,255,255,.75); margin-bottom: auto;
}
.gt-cat h3 { font-size: 25px; line-height: 1.15; margin-bottom: 6px; color: #fff; }
.gt-cat p { font-size: 14px; color: rgba(255,255,255,.78); line-height: 1.45; min-height: 2.9em; }
.gt-cat .gt-cat-go { margin-top: 14px; font-family: var(--gt-sans); font-size: 13.5px; }
.gt-cat .gt-cat-go a {
  color: #fff; text-decoration: none; display: inline-flex; gap: 8px; align-items: center;
}
.gt-cat .gt-cat-go a::after { content: '\2192'; transition: transform .2s; }
.gt-cat:hover .gt-cat-go a::after { transform: translateX(4px); }
/* JS extends the click target to the whole tile; the link itself stays real */
.gt-cat.is-clickable { cursor: pointer; }
.gt-cat:focus-within { outline: 2px solid var(--gt-slate-lt); outline-offset: 3px; }
/* per-tile placeholder variation, removed when real photography lands */
.gt-cat:nth-child(1) { background-image: linear-gradient(200deg, #2C5566, #5B7F8C 55%, #93A7AC); }
.gt-cat:nth-child(2) { background-image: linear-gradient(200deg, #264A59, #4A7080 55%, #8FA5AC); }
.gt-cat:nth-child(3) { background-image: linear-gradient(200deg, #1E3E4B, #3F6675 55%, #7E969E); }
.gt-cat:nth-child(4) { background-image: linear-gradient(200deg, #2A5A63, #4E7C82 55%, #96AAA9); }

/* --------------------------------------------------------------------------
   9. SPLIT PANEL
   -------------------------------------------------------------------------- */
.gt-split { display: grid; grid-template-columns: 1fr 1fr; min-height: 440px; }
.gt-split-copy {
  background: var(--gt-teal); color: #fff;
  padding: clamp(40px,5vw,68px) clamp(28px,4vw,58px) clamp(40px,5vw,68px) var(--gt-gut);
  display: flex; flex-direction: column; justify-content: center;
}
.gt-split-copy h2 { font-size: clamp(26px, 3vw, 38px); line-height: 1.14; margin-bottom: 24px; color: #fff; }
.gt-split-media { position: relative; overflow: hidden; min-height: 300px; }
.gt-checks { list-style: none; margin: 0; padding: 0; display: grid; gap: 13px; }
.gt-checks li {
  position: relative; padding-left: 29px; font-size: 16px;
  color: rgba(255,255,255,.88); line-height: 1.45;
}
.gt-checks li::before {
  content: ''; position: absolute; left: 0; top: 4px; width: 17px; height: 17px;
  background: no-repeat center/contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237FA0B0' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
}


/* --------------------------------------------------------------------------
   9b. AUDIENCE CARDS  (Built Around Relationships)
   -------------------------------------------------------------------------- */
.gt-aud { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--gt-gap); }

/* Designer, 3 Sep: "more height between top text and cards", then 4 Sep in
   the correction doc: back to 64. The export measures 143.5px here, but she
   called 64 looking at it live and live wins over the measurement.
   Selected by what follows the head rather than by the section id, so it
   survives the client renaming or re-inserting the section. */
.gt-sechead:has(+ .gt-aud) { margin-bottom: 64px; }

/* rounded card. Designer, 3 Sep: "radius is a bit more rounded". The export's
   top-left corner reaches the card's left edge 12.5px below its top edge, so
   12px, not the 10 we had. The media sits flush to the top, so its own corners
   have to round with the card. */
.gt-audc { border-radius: 12px; overflow: hidden; }
.gt-audc-media { border-radius: 12px 12px 0 0; overflow: hidden; }
.gt-audc-media figure, .gt-audc-media img { border-radius: inherit; }
/* NO ::after HAIRLINE HERE. It drew a second line: this pseudo-element sat
   inside the h3's content box, and .gt-audc h3's own border-bottom then drew
   again 14px below it. Designer, 3 Sep: "there is a double line below the
   picture placeholder". One line only, and it is the border-bottom. */
.gt-audc {
  background: var(--gt-card); border: 1px solid var(--gt-line);
  display: flex; flex-direction: column;
}
/* The designer's "image card component": photo on top, then heading, rule, body.
   Insert an Image block inside .gt-audc-media; the gradient is the fallback. */
.gt-audc-media {
  position: relative; aspect-ratio: 4 / 3; overflow: hidden; flex: none;
  background-image:
    linear-gradient(115deg, rgba(18,42,51,.5), rgba(18,42,51,.05)),
    linear-gradient(200deg, #2C5566, #5B7F8C 55%, #93A7AC);
  background-size: cover;
}
.gt-audc-media figure { position: absolute; inset: 0; margin: 0; width: 100%; height: 100%; }
.gt-audc-media figure img { width: 100%; height: 100%; object-fit: cover; }

/* Designer, 3 Sep: "bigger titles for tiles". This is H3 on the designer's scale, 36 / 38.2,
   and it does NOT step down with the breakpoints: the cap height measures 25.0px
   in all three exports (1440, 1024 and 393) and the line spacing 38 in each.
   That is why the size is literal here rather than var(--gt-h3), which drops to
   24px below 600. The titles wrap to two lines at every width, as drawn. */
.gt-audc h3 {
  font-size: 36px; line-height: 38.2px;
  margin: 22px 24px 0; padding-bottom: 22px;
  border-bottom: 1px solid var(--gt-line);
  /* Designer, 4 Sep: 75%, "so the words break consistently vs 'real estate /
     professionals' drops to the next line". Narrowing the heading forces all
     three titles onto two lines, and it also shortens the rule to match the
     export, where it runs 313.5px inside a 379.5px content box.
     The min-height is the belt to that braces: it keeps the rule on the same
     line in all three cards even if a title ever fits on one. border-box is
     on, hence padding and border in the sum. */
  max-width: 75%;
  min-height: calc(38.2px * 2 + 23px);
}
.gt-audc p { font-size: var(--gt-small); color: var(--gt-ink); line-height: 1.55; margin: 20px 24px 24px; }

@supports not (aspect-ratio: 4 / 3) { .gt-audc-media { height: 220px; } }

/* --------------------------------------------------------------------------
   9c. FOOTPRINT MAP
   V1 is a static branded image. Drop an Image block into .gt-map-media.
   -------------------------------------------------------------------------- */
.gt-map { display: grid; grid-template-columns: 1fr 1.15fr; gap: clamp(28px, 5vw, 64px); align-items: center; }
/* Designer, 3 Sep: "just increase in size on the header in growing". It is a
   full H2 on the designer's scale, not a reduced one: "A growing residential" measures a
   36px cap height in the export, the same as the section H2s, and the two
   lines sit 54.5px apart against the designer's 53.2 line height. */
.gt-map-copy h2 { font-size: var(--gt-h2); line-height: var(--gt-h2-lh); margin-bottom: 16px; }
/* Designer, 4 Sep: 36px under the lede and under the legend, 64px above the button */
.gt-map-copy p { color: var(--gt-muted); margin-bottom: 36px; }
/* legend: a filled dot at the licensed-market colour */
.gt-map-key {
  display: flex; align-items: center; gap: 12px;
  font-size: 14px; margin-top: 26px; margin-bottom: 36px;
}
.gt-map-key::before {
  content: ''; flex: none; width: 13px; height: 13px; border-radius: 50%;
  background: var(--gt-navy-2);
}
/* the note is preceded by a short rule, as drawn */
/* NOT display:flex. The rule and the sentence are one paragraph containing
   a text node and an <a>; making it a flex container turned those into two
   columns. Absolute positioning keeps the paragraph a paragraph. */
.gt-map-note {
  position: relative; padding-left: 36px;
  font-size: var(--gt-caption); line-height: var(--gt-caption-lh); margin-top: 18px; max-width: 52ch;
}
.gt-map-note::before {
  content: ''; position: absolute; left: 0; top: 10px;
  width: 22px; height: 1px; background: var(--gt-line);
}
.gt-map-note a { display: inline; }   /* Designer, 2 Sep: keep it in the paragraph */
.gt-map-note a::after { content: ' \2192'; }
.gt-map-copy .gt-btns { margin-top: 64px; }
.gt-map-note a { color: var(--gt-slate); }
.gt-map-media { position: relative; min-height: 240px; }
.gt-map-media figure { margin: 0; }
.gt-map-media img { width: 100%; height: auto; object-fit: contain; }
/* The designer's licensed-states map, shipped with the plugin so the section renders
   correctly the moment the pattern is inserted.
   NB :not(:has(img)) rather than :empty: WordPress puts a
   .wp-block-group__inner-container inside the slot, so :empty never matches
   even when no image has been placed. It is decorative here: the
   state list is spelled out in the copy beside it, which is what a screen
   reader and a crawler read. Dropping a core/image into the slot overrides it,
   which is how Graintree swaps in a new export without touching code. */
.gt-map-media:not(:has(img))::before {
  content: ''; display: block; aspect-ratio: 1503 / 1004;
  background: url('../img/us-map-licensed.png') no-repeat center/contain;
}

/* product description inside an open card */
.gt-p-lede { padding-top: 20px; font-size: 15.5px; color: #3C4C53; line-height: 1.6; max-width: 68ch; }

/* --------------------------------------------------------------------------
   10. STICKY ANCHOR NAV
   -------------------------------------------------------------------------- */
.gt-anav {
  position: sticky; top: 0; z-index: 40; background: rgba(248,244,241,.95);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border-block: 1px solid var(--gt-line);
}
.gt-anav-list {
  display: flex; gap: 2px; overflow-x: auto; height: var(--gt-nav-h);
  align-items: stretch; scrollbar-width: none;
  list-style: none; margin: 0; padding-inline: var(--gt-gut);
}
.gt-anav-list::-webkit-scrollbar { display: none; }
.gt-anav-list li { display: flex; margin: 0; }
.gt-anav a {
  display: inline-flex; align-items: center; white-space: nowrap; padding: 0 18px;
  font-size: 13.5px; color: var(--gt-muted); text-decoration: none; border-bottom: 2px solid transparent;
}
.gt-anav a:hover { color: var(--gt-teal); }
.gt-anav a.is-active { color: var(--gt-teal); border-bottom-color: var(--gt-slate); font-weight: 700; }
/* admin bar offset */
.admin-bar .gt-anav { top: 32px; }
@media (max-width: 782px) { .admin-bar .gt-anav { top: 46px; } }

/* --------------------------------------------------------------------------
   11. PRODUCT ACCORDION  (core/details)
   Authoring convention inside the summary field:
       bold  -> category chip
       italic-> one-line description
       plain -> product name
   -------------------------------------------------------------------------- */
.gt-prods { display: grid; gap: 9px; max-width: 960px; }
details.gt-prod {
  background: var(--gt-card); border: 1px solid var(--gt-line);
  transition: border-color .2s; margin: 0;
}
details.gt-prod:hover { border-color: #C4BBB2; }
details.gt-prod[open] { border-color: var(--gt-teal); }
details.gt-prod > summary {
  list-style: none; cursor: pointer; padding: 19px 22px;
  display: flex; align-items: center; gap: 18px;
}
details.gt-prod > summary::-webkit-details-marker { display: none; }
details.gt-prod > summary::marker { content: ''; }
details.gt-prod > summary:focus-visible { outline: 2px solid var(--gt-slate); outline-offset: -3px; }

.gt-p-t { flex: 1; min-width: 0; }
.gt-p-chip {
  display: inline-block; font-family: var(--gt-sans); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--gt-slate); background: #EDF1F3;
  padding: 3px 9px; margin-bottom: 7px;
}
.gt-p-h { display: block; font-family: var(--gt-serif); font-size: 20px; line-height: 1.25; margin-bottom: 3px; }
.gt-p-s { display: block; font-size: 14.5px; color: var(--gt-muted); line-height: 1.45; font-style: normal; }
.gt-p-x {
  flex: none; width: 30px; height: 30px; border: 1px solid var(--gt-line);
  display: grid; place-items: center; font-family: var(--gt-sans); font-size: 18px;
  line-height: 1; color: var(--gt-slate); transition: .2s;
}
.gt-p-x b, .gt-p-x i { font-style: normal; font-weight: 400; grid-area: 1 / 1; }
.gt-p-x i { display: none; }
details.gt-prod[open] .gt-p-x { background: var(--gt-teal); border-color: var(--gt-teal); color: #fff; }
details.gt-prod[open] .gt-p-x b { display: none; }
details.gt-prod[open] .gt-p-x i { display: block; }

.gt-p-body { padding: 0 22px 24px; border-top: 1px solid var(--gt-line); margin-top: 2px; overflow: hidden; }
.gt-p-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px 34px; padding-top: 20px; }
.gt-p-cols h4, .gt-p-body h4 {
  font-family: var(--gt-sans); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gt-slate); font-weight: 700; margin: 0 0 8px;
}
.gt-p-body ul { list-style: none; margin: 0; padding: 0; }
.gt-p-body li {
  font-size: 14.5px; color: #3C4C53; padding-left: 14px; position: relative;
  margin-bottom: 3px; line-height: 1.45;
}
.gt-p-body li::before {
  content: ''; position: absolute; left: 0; top: 9px; width: 6px; height: 1px; background: var(--gt-slate-lt);
}
.gt-p-props ul { display: flex; flex-wrap: wrap; gap: 0 26px; }
.gt-p-cta { margin-top: 20px; }


/* --------------------------------------------------------------------------
   11b. CATEGORY ACCORDION  (Explore Lending Solutions by Need)
   The designer's structure: four bars, programs as columns inside the open panel.

   THREE COLOUR VARIANTS, pending the designer's decision Monday. Swap the modifier on
   .gt-acc and nothing else moves:
       .gt-acc--navy    dark navy bars, light text
       .gt-acc--light   near-white bars, ink borders
       .gt-acc--sage    sage bars, light text
   -------------------------------------------------------------------------- */
.gt-acc { border: 1px solid var(--gt-line); }
.gt-acc details { margin: 0; border-bottom: 1px solid var(--gt-line); }
.gt-acc details:last-child { border-bottom: 0; }

.gt-acc summary {
  list-style: none; cursor: pointer;
  min-height: var(--gt-row-h);
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 0 28px;
  font-family: var(--gt-label); font-size: var(--gt-lbl); font-weight: 700;
  letter-spacing: var(--gt-lbl-ls); text-transform: uppercase;
  transition: background .2s;
}
/* The theme adds `details summary::before` with a PNG icon positioned at
   top: -3.3em, which lands a second marker above each bar and a stray one
   over the section background. One chevron is enough. */
/* Two levels of class so this also wins inside the editor: WordPress
   prefixes the theme's editor styles with .editor-styles-wrapper, which
   lifts `details summary::before` above a single-class rule. */
:is(.gt-page, .editor-styles-wrapper) .gt-acc summary::before { content: none; display: none; }
.gt-acc summary::-webkit-details-marker { display: none; }
.gt-acc summary::marker { content: ''; }
.gt-acc summary:focus-visible { outline: 2px solid var(--gt-navy-2); outline-offset: -3px; }

/* chevron: right when closed, down when open */
.gt-acc summary::after {
  content: ''; flex: none; width: 11px; height: 11px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg); transition: transform .25s var(--gt-ease);
  margin-right: 4px;
}
.gt-acc details[open] > summary::after { transform: rotate(45deg); margin-bottom: 6px; }

/* No border-top. The bronze bar to white panel change is its own edge, so
   this rule was drawing the second line the designer flagged. */
.gt-cat-body { background: var(--gt-card); overflow: hidden; }

/* THEME BUG 6, and the sixth in this one file. customizer-additional.css
   carries a global rule for every <details> on the site:

     details > *:not(summary)       { max-height: 0; opacity: 0;
                                      transform: translateY(-8px);
                                      transition: max-height 1s ease,
                                                  opacity 1s ease,
                                                  transform 1s ease }
     details[open] > *:not(summary) { max-height: none; opacity: 1;
                                      transform: translateY(0) }

   max-height does not interpolate between 0 and none, so the panel snaps
   open instead of growing, and the fade does not replay on a second open.
   The animation is now driven from the toggle event in product-page.js,
   which sets height, opacity and transform inline. Inline wins, so this
   block only takes the theme's dead max-height out of the way rather than
   fighting it, and deliberately leaves the theme transition alone so the
   panel still behaves sanely with our JS disabled. */
.gt-page :is( details.gt-cat-acc, details.gt-prod ) > *:not(summary) {
  max-height: none;
}
.gt-prodcols { display: flex; gap: 0; margin: 0; }
.gt-prodcols .wp-block-column p { font-size: var(--gt-body); line-height: var(--gt-body-lh); }
.gt-prodcols .wp-block-column {
  padding: 44px 36px 52px;
  border-right: 1px solid var(--gt-line);
}
.gt-prodcols .wp-block-column:last-child { border-right: 0; }
/* Designer, 4 Sep: "swap to h4, it actually looked better the way you had it" */
.gt-prodcols h3 { font-size: var(--gt-h4); line-height: 1.25; margin-bottom: 18px; }
.gt-prodcols p  { font-size: var(--gt-small); line-height: var(--gt-body-lh); color: var(--gt-ink); }

/* ---- variant: light bars, ink borders (the designer's default in the file) ---- */
.gt-acc--light summary { background: var(--gt-panel); color: var(--gt-navy-2); }
.gt-acc--light summary:hover { background: #EDEDED; }

/* ---- variant: navy bars ---- */
.gt-acc--navy { border-color: var(--gt-navy-2); }
.gt-acc--navy details { border-bottom-color: rgba(248,244,241,.25); }
.gt-acc--navy summary { background: var(--gt-navy-2); color: var(--gt-on-dark); }
.gt-acc--navy summary:hover { background: #2E4354; }
.gt-acc--navy .gt-cat-body { border-top-color: var(--gt-navy-2); }

/* ---- variant: bronze bars — the approved one (1 Sep) ---- */
.gt-acc--bronze { border-color: var(--gt-bronze); }
.gt-acc--bronze details { border-bottom-color: rgba(248,244,241,.35); }
.gt-acc--bronze summary { background: var(--gt-bronze); color: var(--gt-on-dark); }
.gt-acc--bronze summary:hover { background: #6F6050; }
.gt-acc--bronze .gt-cat-body { border-top-color: var(--gt-bronze); }

/* ---- variant: sage bars ---- */
.gt-acc--sage { border-color: var(--gt-sage); }
.gt-acc--sage details { border-bottom-color: rgba(248,244,241,.4); }
.gt-acc--sage summary { background: var(--gt-sage); color: var(--gt-on-dark); }
.gt-acc--sage summary:hover { background: #9C9990; }
.gt-acc--sage .gt-cat-body { border-top-color: var(--gt-sage); }

/* centred section head, used by this section */
/* 740px, not 62ch. The export's lede sets 3 lines with a widest line of
   727.5px; at 62ch (about 624px) it broke to four. */
.gt-sechead--center { max-width: 860px; margin-inline: auto; text-align: center; }

/* --------------------------------------------------------------------------
   12. BUTTONS
   Native core/button blocks. The gt-btn classes go on the block wrapper
   (set in "Additional CSS class(es)"), the styling lands on the link inside.
   Variants: gt-btn--light, gt-btn--ghost, gt-btn--solid, gt-btn--line.
   Add gt-btn--plain to suppress the arrow.
   -------------------------------------------------------------------------- */
.gt-btns { display: flex; flex-wrap: wrap; gap: 12px; }
.gt-btns .wp-block-button__link,
:is(.gt-page, .editor-styles-wrapper) a.gt-btn {
  display: inline-flex; align-items: center; gap: 9px; font-family: var(--gt-sans);
  font-family: var(--gt-label); font-size: 13px; line-height: 1.2;
  letter-spacing: var(--gt-lbl-ls); text-transform: uppercase; text-decoration: none;
  min-height: var(--gt-btn-h); padding-inline: var(--gt-btn-px); padding-block: 0;
  border: 1px solid transparent; border-radius: var(--gt-radius);
  background: transparent; cursor: pointer; transition: .2s;
}
/* No arrow on buttons: the designer's are plain uppercase labels. The arrow is
   kept for the inline advisor links, which do carry one. Add gt-btn--arrow
   to put it back on a button. */
.gt-btn--arrow .wp-block-button__link::after,
:is(.gt-page, .editor-styles-wrapper) a.gt-btn--arrow::after {
  content: '\2192'; transition: transform .2s;
}
.gt-btn--plain .wp-block-button__link::after,
:is(.gt-page, .editor-styles-wrapper) a.gt-btn--plain::after { content: none; }
.gt-btn .wp-block-button__link:hover::after,
:is(.gt-page, .editor-styles-wrapper) a.gt-btn:hover::after { transform: translateX(3px); }

.gt-btn--paper .wp-block-button__link, a.gt-btn--paper {
  background: var(--gt-paper); color: var(--gt-ink); border-color: var(--gt-line);
}
.gt-btn--paper .wp-block-button__link:hover, a.gt-btn--paper:hover { background: #fff; }
.gt-btn--light .wp-block-button__link, a.gt-btn--light { background: #fff; color: var(--gt-teal); }
.gt-btn--light .wp-block-button__link:hover, a.gt-btn--light:hover { background: var(--gt-slate-lt); color: #fff; }
/* WRONG, AND CORRECTED ON THE CALL, 8 Sep. We read the two hero buttons in the
   export as one button in two states, the filled one being the hover. Both
   buttons were changed to --ghost on that reading.

   They are two buttons. The designer, asked directly whether the filled one
   was a hover state: "no, neither of those are a hover state. Those were from
   Eric's brand guidelines. He had designated a primary button, which is the
   white one, and the second button is the transparent."

   So the pairing that was on the page all along was right, and the change was
   the mistake. Reverted: Explore Solutions is --light (primary, white), Speak
   With an Advisor is --ghost (secondary, transparent).

   STILL OUTSTANDING: the hover states below are ours, not Eric's. He has
   designated hovers in the brand guidelines and we have not seen that
   document. Until we do, --light hovers to slate and --ghost fills to paper,
   both of which are guesses that merely look reasonable. Ask for the file. */
.gt-btn--ghost .wp-block-button__link, a.gt-btn--ghost {
  border-color: rgba(248,244,241,.45); color: var(--gt-on-dark); background: transparent;
}
.gt-btn--ghost .wp-block-button__link:hover, a.gt-btn--ghost:hover {
  background: var(--gt-paper); border-color: var(--gt-paper); color: var(--gt-navy);
}
.gt-btn--solid .wp-block-button__link, a.gt-btn--solid { background: var(--gt-teal); color: #fff; }
.gt-btn--solid .wp-block-button__link:hover, a.gt-btn--solid:hover { background: var(--gt-slate); }
.gt-btn--line .wp-block-button__link, a.gt-btn--line { border-color: var(--gt-teal); color: var(--gt-teal); }
.gt-btn--line .wp-block-button__link:hover, a.gt-btn--line:hover { background: var(--gt-teal); color: #fff; }

/* --------------------------------------------------------------------------
   13. CLOSING CTA
   -------------------------------------------------------------------------- */
/* Mid-page CTA. Measured 492px tall in the design, roughly half again the
   standard band, so it gets its own padding rather than --gt-band. */
.gt-cta-band { background: var(--gt-sage); padding-block: clamp(72px, 9vw, 132px); }
.gt-cta-inner { text-align: center; }
.gt-cta-inner h2 { font-size: clamp(28px, 3.6vw, 44px); line-height: 1.12; margin-bottom: 16px; }
.gt-cta-inner > p { max-width: 56ch; margin-inline: auto; }
.gt-cta-inner .gt-btns { justify-content: center; margin-top: 34px; }

.gt-close { background: var(--gt-bronze); color: var(--gt-on-dark); text-align: center; position: relative; overflow: hidden; }
.gt-close::before {
  content: ''; position: absolute; inset: 0; opacity: .4;
  background: radial-gradient(70% 120% at 50% 0%, rgba(248,244,241,.16), transparent 62%);
}
.gt-close-inner { padding-block: clamp(56px,7vw,88px); position: relative; z-index: 1; }
.gt-close h2 { font-size: clamp(28px, 3.8vw, 46px); margin-bottom: 14px; color: var(--gt-on-dark); }
/* Designer, 3 Sep: wider. 48ch measured about 427px live and broke this to four
   lines; the export sets it in three, 649.5 / 669 / 579.5 wide. Anything under
   670 wraps early and anything from about 697 pulls "estate" up to line 1. */
.gt-close p { color: rgba(248,244,241,.88); max-width: 680px; margin: 0 auto 30px; }
.gt-close .gt-btns { justify-content: center; }

/* advisor contacts, inside the closing band */
.gt-advisors {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 28px; max-width: 620px; margin: 44px auto 0;
  padding-top: 32px;   /* Designer, 2 Sep: no horizontal rule here */
}
/* NO DIVIDER between the two advisors. The 1 Sep export draws a vertical rule
   here, but the designer overrode it on 3 Sep: "no line between jason and gary".
   Keeping the inline padding so the two columns still hold their measure. */
.gt-advisors .gt-advisor { padding-inline: 22px; position: relative; }
/* Designer, 4 Sep: the label face "is getting overwritten by a p tag font".
   She is right, and it is the theme: it ships a bare `p { font-family: ... }`
   with !important, so nothing but !important reaches this. Fourth theme bug. */
.gt-close .gt-advisor-name {
  font-family: var(--gt-label) !important; font-size: 14px; font-weight: 400;
  letter-spacing: var(--gt-lbl-ls); text-transform: uppercase;
}
/* Designer, 4 Sep: 12px on the bottom and nothing else, and Ashley the same
   day: "the spacing ... seems a little wide, can that be condensed?".
   Scoped under .gt-close for specificity (0,2,0) rather than !important:
   these are <p>, and our own `:is(.gt-hero, .gt-band, ...) p { margin: 0 }`
   is (0,1,1), which is what was eating the margins. */
.gt-close :is(.gt-advisor-name, .gt-advisor-nmls, .gt-advisor-link) { margin: 0 0 12px; }
.gt-close .gt-advisor-nmls { font-size: var(--gt-body); line-height: 1.5; }
.gt-close .gt-advisor-link:last-child { margin-bottom: 0; }
.gt-advisor-link a {
  color: var(--gt-on-dark); font-size: var(--gt-body);
  text-decoration: underline; text-underline-offset: 3px;
}
/* no arrow: these are addresses and numbers, not calls to action */
.gt-advisor-link a::after { content: none; }

@media (max-width: 600px) {
  .gt-advisors { grid-template-columns: 1fr; gap: 0; }
  /* no divider when they stack either, per the designer, 3 Sep. The spacing does the
     separating on its own. */
  .gt-advisors .gt-advisor + .gt-advisor { padding-top: 40px; margin-top: 40px; }
}

/* --------------------------------------------------------------------------
   14. COMPLIANCE / DISCLOSURE BLOCK (in-page)

   NOTE, 9 Sep: the footer licensing disclosure also carries .gt-legal, but its
   rules are scoped `body.gt-page footer.footer` at (0,4,3) and outrank this
   block on every property, so the two cannot collide. Nothing in the pattern
   set currently uses this rule; it is kept in case the page body carries one.
   -------------------------------------------------------------------------- */
.gt-legal {
  border-top: 1px solid var(--gt-line); padding-block: 24px;
  font-size: 12px; line-height: 1.6; color: #7A868C;
}

/* --------------------------------------------------------------------------
   15. MOTION + RESPONSIVE
   -------------------------------------------------------------------------- */
.gt-rv { opacity: 0; transform: translateY(12px); transition: opacity .55s var(--gt-ease), transform .55s var(--gt-ease); }
.gt-rv.is-in { opacity: 1; transform: none; }

/* Designer, 4 Sep: "can we have an easeful transition when you click on the
   anchor links ... so it's not so much a snap to? I.e. like the same pace as
   the line being drawn out". Scoped through :has so it only applies on pages
   carrying our sections, never the rest of the site. The accordion's own
   opening animation is matched to the same .55s in product-page.js. */
html:has(body.gt-page) { scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  .gt-rv { opacity: 1; transform: none; transition: none; }
  html, html:has(body.gt-page) { scroll-behavior: auto; }
}

/* ==========================================================================
   RESPONSIVE
   Two bands, matched to the theme's own breakpoints so the header and the
   content switch together:
     <= 976px  tablet   (theme swaps to the mobile nav here)
     <= 600px  phone    (theme steps heading sizes down here)
   ========================================================================== */

/* ---------------- tablet ---------------- */
@media (max-width: 976px) {
  /* hero: less letterboxing, copy sits closer to the top */
  .gt-hero--full { min-height: clamp(420px, 62vh, 560px); }
  .gt-hero--full h1 { max-width: 100%; }

  .gt-hero--split .gt-hero-grid { grid-template-columns: 1fr; }
  .gt-hero--split .gt-hero-media { min-height: 240px; order: -1; }

  .gt-split { grid-template-columns: 1fr; }
  .gt-split-media { min-height: 220px; }
  /* Map above the copy once this stacks. The iPhone export puts the map
     first, then the heading, then the body. DOM order is copy-then-media so
     the desktop two-column layout reads correctly, so this flips it visually
     without touching the markup. Verified at 393; the 1024 export is still
     two-column so the stacked order above 600 is inferred, not measured. */
  .gt-map { grid-template-columns: 1fr; }
  .gt-map-media { order: -1; }

  /* THE WHOLE MAP COLUMN CENTRES ONCE IT STACKS. Julian, 9 Sep: centre the
     paragraph and the disclosures line too.

     Three separate reasons it was not already centred, and only one of them
     was the obvious one:

     1. WRONG BREAKPOINT. This was at 600px while the map stacks at 976, so
        between 601 and 976 the layout was single column and the copy was
        still ranged left. It belongs here.

     2. THE BLOCKS CARRY THEIR OWN ALIGNMENT. The client set these in the
        editor, so the markup is <p class="has-text-align-left">, and core
        styles that class directly. Centring the PARENT, which is what the
        designer's `.gt-map-copy { text-align: center }` does, cannot win:
        the child overrides the inherited value with its own. The alignment
        classes have to be named to be beaten, which is what the selectors
        below do at (0,3,1) against core's (0,1,0).

     3. .gt-map-key IS A FLEX ROW, so text-align has nothing to act on: the
        dot is a ::before and the label an anonymous flex item, both laid out
        on the main axis. justify-content is the property that moves them.
        Worth knowing, because the same trap catches every flex row.

     .gt-map-note is a fourth case: one paragraph with the short rule drawn as
     an absolutely positioned ::before, so it does centre with text-align, but
     the 36px left padding that clears that rule has to go or the centred text
     sits 36px off true, and the rule itself has to move to the middle. */
  .gt-page .gt-map-copy,
  .gt-page .gt-map-copy h2,
  .gt-page .gt-map-copy p,
  .gt-page .gt-map-copy p.has-text-align-left,
  .gt-page .gt-map-copy .gt-map-note.has-text-align-left {
    text-align: center;
  }
  .gt-page .gt-map-note {
    padding-left: 0;
    max-width: none;
    margin-inline: auto;
  }
  .gt-page .gt-map-note::before { left: 50%; transform: translateX(-50%); top: -10px; }
  .gt-page .gt-map-key { justify-content: center; }

  /* Type steps here, not before. The 1024 export is byte-identical to 1440,
     so anything above 976 keeps the desktop sizes. */
  :root, .gt-band, .gt-hero { --gt-h1: 64px; --gt-h1-lh: 69px; }
  .gt-sechead--center { max-width: 100%; }

  /* pillars: 2 x 2 rather than 3 + 1 orphan */
  .gt-pillars--tiles { grid-template-columns: repeat(2, 1fr); }
  .gt-pill { border-right: 0; }
  .gt-pillars--tiles .gt-pill { border: 1px solid var(--gt-line); }

  /* cards: about a card and a half in view, so the row reads as scrollable.
     The taller centred card is a desktop-only comparison; with one card on
     screen there is nothing to compare it against. */
  .gt-uw--row { --gt-uwc-w: min(62vw, 428px); }
  .gt-uw--row .gt-uwc.is-active { min-height: 428px; }
  .gt-uw--row { min-height: 460px; }   /* no taller card here, so no reserve */
  .gt-aud { gap: 18px; }

  /* audience cards: keep 3 across so there is no orphan, and shorten the
     media so the cards do not become towers */
  .gt-aud { grid-template-columns: repeat(3, 1fr); gap: 14px; }
  .gt-audc-media { aspect-ratio: 4 / 3; }
  /* Three cards in a narrowing viewport. 36px holds at 1024 (measured on the
     iPad export) but "Professionals" would overflow a 171px card at 601, so
     the title scales between those two rather than sitting at either end.
     3.6vw lands on 35.1 at 976 and 21.6 at 601. */
  .gt-audc h3 {
    font-size: clamp(21px, 3.6vw, 36px); line-height: 1.061;
    margin: 20px 18px 0; padding-bottom: 16px;
    min-height: calc(2.122em + 17px);   /* two lines + padding + border */
  }
  .gt-audc p { font-size: 15px; margin: 16px 18px 22px; }

  /* accordion: programs stack, panel padding comes in */
  .gt-prodcols { flex-direction: column; }
  .gt-prodcols .wp-block-column {
    border-right: 0; border-bottom: 1px solid var(--gt-line); padding: 30px 24px 34px;
  }
  .gt-prodcols .wp-block-column:last-child { border-bottom: 0; }
  .gt-acc summary { padding: 0 20px; min-height: 62px; }

  .gt-p-cols { grid-template-columns: 1fr 1fr; }
  .gt-sechead { margin-bottom: 64px; }
}

/* The designer's header drops to `padding: 24px 16px` at 767px, so the logo
   moves to 16 and the hero edge has to follow it. Same breakpoint as hers, not
   ours, because the pair has to change together. */
@media (max-width: 767px) {
  :root { --gt-edge: 16px; }
}

/* ---------------- phone ---------------- */
@media (max-width: 600px) {
  /* hero: the copy is the whole screen here, so trim the frame */
  .gt-hero--full { min-height: clamp(400px, 68vh, 520px); }
  .gt-hero--full .gt-hero-copy { padding-block: clamp(40px, 12vw, 64px); }
  .gt-hero-rule { margin: 40px 0 48px !important; }   /* !important: see the base rule */

  /* long eyebrows wrap badly at this width */
  /* One rung down the designer's scale rather than invented numbers: H2 takes H3's
     size, H3 takes H4's, the eyebrow takes Eyebrow 2. H1 at 48 is measured
     off the iPhone export. */
  :root, .gt-band, .gt-hero, .gt-close, .gt-cta-band {
    --gt-h1: 48px; --gt-h1-lh: 53px;   /* measured 53px line spacing */
    --gt-h2: 36px; --gt-h2-lh: 38.2px; /* measured 38px, wraps to 2 lines */
    --gt-h3: 24px; --gt-h3-lh: 30px;
    --gt-lbl: 13px;                    /* Eyebrow 2. Measured 147.5px wide */
    /* Ledes drop to Body 1 here. Measured ink height is 15px per line, which
       is 16px type, not the 19px Body Large used above 600. Line height stays
       25.5 either way, so only the ink height separates them. */
    --gt-body-lg: 16px;
    /* NOT 56. The export measures ~70px from band top to the first ink, and
       the designer asked for 72 on all components. */
    --gt-band: 72px;
  }
  /* FIFTH THEME BUG, found 3 Sep and this one does block mobile.
     themes/landing-page-theme/customizer-additional.css carries, inside its own
     (max-width: 600px) block:
         .wp-block-heading { font-size: 45px !important; }
     WordPress puts .wp-block-heading on every core/heading, so all 31 headings
     on this page rendered at 45px on a phone: the pillar titles at 45px on a
     30px line height, the card titles at 45px in a 349px card. Our line heights
     survived, only the sizes were taken, which is why it reads as overlap.
     !important is the only answer to !important, so answer it in kind and keep
     it scoped to our four section roots. Levels first, exceptions after.
     Remove this block once the theme rule is gone. */
  :is(.gt-hero, .gt-band, .gt-close, .gt-cta-band) h1 { font-size: var(--gt-h1) !important; }
  :is(.gt-hero, .gt-band, .gt-close, .gt-cta-band) h2 { font-size: var(--gt-h2) !important; }
  :is(.gt-hero, .gt-band, .gt-close, .gt-cta-band) h3 { font-size: var(--gt-h3) !important; }
  :is(.gt-hero, .gt-band, .gt-close, .gt-cta-band) h4 { font-size: var(--gt-h4) !important; }
  /* the audience card title is the one heading that does not step down: the
     iPhone export measures the same 25.0px cap height as the desktop one */
  .gt-audc h3 { font-size: 36px !important; }

  /* measured 63.5px from lede ink to the tiles */
  .gt-sechead { margin-bottom: 64px; }
  .gt-eyebrow { letter-spacing: .16em; margin-bottom: 16px; }
  .gt-hero-rule { margin: 32px 0 40px !important; }   /* !important: see the base rule */
  .gt-pillars--tiles .gt-pill { padding: 44px 22px 44px; }
  .gt-pillars--tiles .gt-pill h3 { margin-bottom: 18px; }
  .gt-pill[class*="gt-pico--"]::before { margin-bottom: 22px; }

  /* everything goes single column */
  .gt-pillars--tiles { grid-template-columns: 1fr; }
  .gt-pill[class*="gt-pico--"]::before { width: 36px; height: 36px; margin-bottom: 20px; }

  /* one card per screen, matching the mobile design */
  .gt-uw--row { gap: 20px; min-height: 460px; }
  .gt-cta-inner .gt-btns, .gt-map-copy .gt-btns { justify-content: center; }
  .gt-uw--row { --gt-uwc-w: calc(100vw - var(--gt-gut) * 2); }
  .gt-uw--row .gt-uwc { padding: 22px; }
  .gt-uw--row .gt-uwc::after { width: 80px; height: 78px; top: 14px; right: 16px; }
  .gt-uw--row .gt-uwc h3::after { width: 100%; }
  .gt-aud { grid-template-columns: 1fr; }
  .gt-audc-media { aspect-ratio: 16 / 9; }
  /* single column at 349px, so the title goes back to its measured 36 / 38.2.
     The iPhone export gives the same 25.0px cap height as the desktop one. */
  .gt-audc h3 { font-size: 36px; line-height: 38.2px; margin: 22px 24px 0; padding-bottom: 22px; min-height: calc(38.2px * 2 + 23px); }
  .gt-audc p { font-size: var(--gt-small); margin: 20px 24px 24px; }
  /* the head-to-cards gap is 47px here, not the desktop 140 */
  .gt-sechead:has(+ .gt-aud) { margin-bottom: 64px; }
  .gt-p-cols { grid-template-columns: 1fr; }

  .gt-prodcols .wp-block-column { padding: 26px 20px 30px; }
  .gt-acc summary { font-size: 13px; letter-spacing: .1em; gap: 14px; }
  .gt-acc summary::after { width: 9px; height: 9px; }

  /* stacked, full-width buttons are easier to hit */
  /* Auto width, not stretched. The export's hero buttons measure 242.5 and
     278.5 wide against a 353px column, so they size to their label. */
  .gt-btns { flex-direction: column; align-items: flex-start; }
  .gt-cta-inner .gt-btns, .gt-map-copy .gt-btns { align-items: center; }

  /* Map centring moved up to the 976px block, where the map actually
     stacks. See the note there. */
  /* core/button's wrapper stretches on its own; without this the flex-start
     alignment has nothing to shrink */
  .gt-btns .wp-block-button { width: auto; max-width: 100%; }
  .gt-btns .wp-block-button__link { justify-content: center; }   /* label centred, box still auto-width */

  /* superseded: the export measures 63.5px from lede ink to the tiles */

  .gt-map-media:not(:has(img))::before { min-height: 220px; }
}

/* ---------------- pointer-coarse touches ---------------- */
@media (hover: none) {
  /* hover lifts do nothing on touch and can leave a stuck state */
  .gt-uwc:hover { transform: none; }
}

/* --------------------------------------------------------------------------
   16. EDITOR
   Keeps the patterns legible inside the block editor without fighting it.
   -------------------------------------------------------------------------- */
.editor-styles-wrapper .gt-hero-media,
.editor-styles-wrapper .gt-split-media,
.editor-styles-wrapper .gt-cat { min-height: 220px; }
.editor-styles-wrapper details.gt-prod > summary { display: block; }

/* ==========================================================================
   16. THE BLOCK EDITOR
   The editor loads this stylesheet but never runs product-page.js, and its
   canvas is not the front end: 100vw is the browser window, not the frame,
   and absolutely positioned media layers sit on top of the text you are
   trying to click. Everything below exists so the page can be edited in
   place. None of it reaches the front end.
   ========================================================================== */

/* THE BIG ONE. .gt-rv starts at opacity:0 and waits for JS to add .is-in.
   No JS in the editor means every revealed block is invisible: you see the
   band colours and nothing else, and the content only shows in List View. */
.editor-styles-wrapper .gt-rv { opacity: 1; transform: none; transition: none; }

/* The hero photo layer covers the copy and swallows clicks. Unstack it. */
.editor-styles-wrapper .gt-hero--full { min-height: 0; }
.editor-styles-wrapper .gt-hero--full .gt-hero-media {
  position: relative; inset: auto; min-height: 200px;
}
.editor-styles-wrapper .gt-hero--full::after { content: none; }
.editor-styles-wrapper .gt-hero--full .gt-hero-copy { padding-block: 40px; }

/* The card row breaks out with calc(50vw - 50%), which in the editor measures
   the browser window rather than the canvas and shoots off the frame. Show
   the cards as a plain wrapped grid instead: all six visible, all editable. */
.editor-styles-wrapper .gt-uw--row {
  margin-inline: 0; padding-inline: 0; min-height: 0;
  display: flex; flex-wrap: wrap; gap: 16px; overflow: visible;
}
.editor-styles-wrapper .gt-uw--row .gt-uwc,
.editor-styles-wrapper .gt-uw--row .gt-uwc.is-active {
  flex: 1 1 260px; min-height: 200px;
}
.editor-styles-wrapper .gt-uw--row .gt-uwc.is-active::after { content: none; }

/* Label the empty media slots so they are findable and obviously droppable.
   Front end never sees this: an empty slot there just shows its gradient. */
.editor-styles-wrapper :is(.gt-hero-media, .gt-audc-media, .gt-map-media):not(:has(img))::after {
  content: 'Image slot \2014 insert an Image block here';
  display: grid; place-items: center; min-height: 120px; height: 100%;
  font-family: var(--gt-sans); font-size: 11px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.55); text-align: center;
  padding: 12px;
}
.editor-styles-wrapper .gt-map-media:not(:has(img))::after {
  color: var(--gt-ink); text-shadow: none;
}

/* Give every section a little breathing room so blocks are easy to hit. */
.editor-styles-wrapper .gt-band,
.editor-styles-wrapper .gt-cta-band { padding-block: 40px; }

/* Designer, 2 Sep: hide the horizontal scrollbar on the card row. scrollbar-width
   covers Firefox and current Chrome; the pseudo-element covers older WebKit. */
.gt-uw--row::-webkit-scrollbar { width: 0; height: 0; display: none; }
/* The row is a scrollable region, so it has to be reachable and operable by
   keyboard in its own right, not only through the arrows. JS gives it
   tabindex, a role and a label; this makes the focus visible. */
.gt-uw--row:focus-visible {
  outline: 2px solid var(--gt-paper); outline-offset: -4px;
  box-shadow: inset 0 0 0 6px rgba(18,43,52,.9);
}
