/* ==========================================================================
   NFIS Mortgage Brokers — shared site stylesheet
   --------------------------------------------------------------------------
   The service/loan pages were produced by a design-export tool and carry their
   layout in inline style attributes. Inline styles win the cascade, so the
   responsive rules here must use !important to override them. That is
   deliberate and scoped to breakpoints only — it is not a specificity crutch.

   Load order on every page:  <link nfis.css>  then  <script nfis.js defer>

   Sections
     1. Tokens
     2. Base + accessibility
     3. Interaction states (transitions, hover, focus)
     4. Responsive layout
     5. Overflow containment
     6. Mobile navigation (markup injected by nfis.js)
     7. Motion / scroll reveals
     8. Reduced motion
   ========================================================================== */

/* ---------- 1. Tokens ---------------------------------------------------- */
:root {
  --sage: #5B7B5E;
  --sage-deep: #3D5A40;
  --sage-light: #8BAF8E;
  --sage-pale: #E8F0E9;
  --sage-wash: #F4F7F5;
  --terracotta: #C4734F;
  --cream: #FDF9F3;
  --cream-warm: #F7F0E6;
  --charcoal: #3A3A3A;
  --warm-grey: #6B6760;

  /* Motion. Ease-out-quint: decisive start, soft settle. No bounce. */
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --dur-fast: .18s;
  --dur-base: .3s;
  --dur-slow: .7s;

  --z-nav: 200;
  --z-drawer: 250;
  --z-skip: 300;
}

/* ---------- 2. Base + accessibility -------------------------------------- */

/* The exporter emitted its own streaming-placeholder scaffolding into every
   page (.sc-placeholder, .sc-dc-streaming, sc-shine). It is dead weight in
   production; neutralise any that remains. */
.sc-placeholder,
.sc-placeholder-error {
  background: none !important;
  border: none !important;
}
.sc-placeholder::before {
  content: none !important;
  animation: none !important;
}

/* Skip link — keyboard users land here first. */
.nfis-skip {
  position: fixed;
  top: -100px;
  left: 1rem;
  z-index: var(--z-skip);
  background: var(--sage);
  color: #fff;
  padding: .75rem 1.25rem;
  border-radius: 10px;
  font-weight: 600;
  transition: top var(--dur-base) var(--ease-out);
}
.nfis-skip:focus { top: 1rem; }

/* ---------- 3. Interaction states ---------------------------------------- */
/* The export gave these elements :hover rules but no transition, so every
   hover snapped instantly. This is the single biggest reason the pages felt
   unfinished. Transitions are declared here, on the element's resting state. */

.scp0, .scp1, .scp2, .scp3, .scp4,
.scp5, .scp6, .scp7, .scp8 {
  transition:
    background-color var(--dur-base) var(--ease-out),
    border-color     var(--dur-base) var(--ease-out),
    box-shadow       var(--dur-base) var(--ease-out),
    color            var(--dur-base) var(--ease-out),
    transform        var(--dur-base) var(--ease-out);
}

/* Nav links get an underline that grows from the left rather than a bare
   colour swap — reads as intentional, costs one pseudo-element. */
nav .nfis-links a {
  position: relative;
  padding-bottom: 2px;
}
nav .nfis-links a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1.5px;
  background: var(--sage-deep);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-out);
}
nav .nfis-links a:hover::after,
nav .nfis-links a:focus-visible::after { transform: scaleX(1); }

/* Buttons: press feedback. Hover lift is already defined per-page (.scp2);
   this adds the acknowledgement on click that was missing. */
.scp1:active, .scp2:active, .scp3:active { transform: translateY(0) scale(.985); }

/* Cards lift on hover. .scp4/.scp5/.scp7 already shift shadow; add the
   translate where it was missing so the whole family behaves consistently. */
.scp5:hover { transform: translateY(-2px); }

/* Carousel arrows — give them a real hover and press state. */
[aria-label="Previous reviews"],
[aria-label="Next reviews"] {
  transition:
    background-color var(--dur-base) var(--ease-out),
    border-color     var(--dur-base) var(--ease-out),
    transform        var(--dur-base) var(--ease-out);
}
[aria-label="Previous reviews"]:hover,
[aria-label="Next reviews"]:hover {
  background: rgba(255, 255, 255, .22) !important;
  border-color: rgba(255, 255, 255, .55) !important;
}
[aria-label="Previous reviews"]:active,
[aria-label="Next reviews"]:active { transform: translateY(-50%) scale(.93); }

/* Reviews carousel track — dc.js sets transform inline; ease it. */
[aria-label="Previous reviews"] ~ div > div[style*="translateX"],
[aria-label="Previous reviews"] ~ div > div[style*="translatex"] {
  transition: transform .55s var(--ease-out);
}

/* FAQ disclosure. Native <details>; animate the marker, not the height. */
summary { cursor: pointer; transition: color var(--dur-base) var(--ease-out); }
summary:hover { color: var(--sage-deep); }
details[open] summary .nfis-caret,
details[open] summary svg { transform: rotate(180deg); }
summary .nfis-caret,
summary svg { transition: transform var(--dur-base) var(--ease-out); }

/* Focus-visible. There was no focus styling anywhere on the site — keyboard
   users had no idea where they were. Non-negotiable. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2.5px solid var(--sage-deep);
  outline-offset: 3px;
  border-radius: 4px;
}
/* On dark/sage panels the deep-sage ring disappears; go light there. */
[style*="background: rgb(61, 90, 64)"] a:focus-visible,
[style*="background: rgb(61, 90, 64)"] button:focus-visible,
[style*="background: rgb(91, 123, 94)"] a:focus-visible,
[style*="background: rgb(91, 123, 94)"] button:focus-visible {
  outline-color: #fff;
}

/* Images shouldn't stretch past their box. */
img { max-width: 100%; height: auto; }

/* ---------- Tap targets -------------------------------------------------- */
/* WCAG 2.2 (2.5.8) sets a 24x24 CSS-px floor; 44x44 is the comfortable
   touch standard. The reviews pagination dots render at 10x10 — far too
   small to hit reliably. Expand the hit area with a pseudo-element so the
   dot keeps its visual size. */
[aria-label^="Reviews page"] {
  position: relative;
  transition: background-color var(--dur-base) var(--ease-out);
}
[aria-label^="Reviews page"]::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

@media (max-width: 768px) {
  /* Footer link columns sit at ~22px line boxes stacked directly on top of
     each other — easy to mis-tap the neighbour. Padding separates them
     without redrawing the footer. */
  footer a { padding-block: .35rem; display: inline-block; }
}

/* ---------- 4. Responsive layout ----------------------------------------- */
/* The export pages had three media queries and all three were nav rules —
   zero layout breakpoints. Grids stayed at 3 and 4 columns on a phone.
   Breakpoints mirror index.html (1024 / 768) for consistency. */

@media (max-width: 1024px) {
  /* 4-up feature/stat rows → 2-up */
  [style*="grid-template-columns: repeat(4, 1fr)"] {
    grid-template-columns: repeat(2, 1fr) !important;
  }
  /* 3-up card rows → 2-up */
  [style*="grid-template-columns: repeat(3, 1fr)"] {
    grid-template-columns: repeat(2, 1fr) !important;
  }
  /* Hero and split sections → stacked */
  [style*="grid-template-columns: 1.1fr 0.9fr"],
  [style*="grid-template-columns: 0.9fr 1.1fr"] {
    grid-template-columns: 1fr !important;
    gap: 2.5rem !important;
  }
  /* Footer 4-col → 2-col */
  [style*="grid-template-columns: 2fr 1fr 1fr 1fr"] {
    grid-template-columns: 1fr 1fr !important;
    gap: 2.5rem !important;
  }
}

/* Portrait tablet. Card rows go single-column for readable line lengths, but
   compact 4-up stat rows still read well two-across — collapsing those to one
   column here just makes the page long for no gain. */
@media (max-width: 768px) {
  [style*="grid-template-columns: repeat(3, 1fr)"],
  [style*="grid-template-columns: repeat(2, 1fr)"],
  [style*="grid-template-columns: 1fr 1fr"] {
    grid-template-columns: 1fr !important;
  }

  /* Section padding was tuned for desktop; tighten the foot but keep enough
     head room to clear the fixed nav (~76px + breathing space). */
  section[style*="padding: 150px"] { padding-top: 128px !important; }
  section[style*="6rem"] { padding-bottom: 3.5rem !important; }

  /* Display type: the clamp maxima were set for wide viewports and caused
     long words ("Refinancing", "finance.") to dominate the screen. */
  h1 { font-size: clamp(2rem, 8.5vw, 2.6rem) !important; line-height: 1.2 !important; }
  h2 { font-size: clamp(1.5rem, 6vw, 1.9rem) !important; }

  /* Floating quote/stat cards are absolutely positioned and hang off the
     edge. Return them to normal flow on small screens — and stack their
     wrapper, or they land beside the image in the parent flex row instead
     of beneath it. */
  [style*="position: absolute"][style*="max-width: 230px"] {
    position: static !important;
    max-width: 100% !important;
    margin-top: 1.25rem;
  }
  section [style*="display: flex"][style*="justify-content: flex-end"] {
    flex-direction: column !important;
    align-items: stretch !important;
  }


  /* Carousel arrows live at left/right:-62px — entirely off-screen on a
     phone. Bring them inside the rail. */
  [aria-label="Previous reviews"] { left: 4px !important; }
  [aria-label="Next reviews"] { right: 4px !important; }

  /* Give edge-to-edge sections breathing room. */
  [style*="padding: 0px 1.75rem"],
  [style*="padding: 0 1.75rem"] { padding-left: 1.25rem !important; padding-right: 1.25rem !important; }
}

/* Body copy line length. Long-form paragraphs were running the full 1200px
   container on wide screens — well past the 75ch comfortable ceiling. */
@media (min-width: 1025px) {
  section p:not([style*="max-width"]) { max-width: 72ch; }
}

/* Calculators page: below 900px the page's own rule already turns the sidebar
   into a wrapped chip grid (display:flex; flex-wrap:wrap) with the group
   headings on their own full-width rows. That intent is sound — every option
   stays visible with no hidden-scroll affordance.
   The one gap: .calc-tab keeps width:100% from the desktop rule, so each chip
   claimed a full row and pushed the calculator a screen and a half down the
   page. Sizing chips to their content packs them 2-3 per row instead. */
@media (max-width: 900px) {
  .calc-tab {
    width: auto;
    flex: 0 0 auto;
    white-space: nowrap;
    border: 1.5px solid var(--sage-pale);
    background: var(--white);
  }
  .calc-tab.on {
    background: var(--sage);
    border-color: var(--sage);
    color: var(--white);
  }
  .calc-panel-wrap { padding: 1.5rem 1.25rem; }
}

/* ---------- 5. Overflow containment -------------------------------------- */
/* Decorative circles sit at top:-100px; right:-100px and pushed the document
   wider than the viewport, producing a horizontal scrollbar on mobile.
   Clipping them at the section is enough.

   Do NOT add `overflow-x: hidden` to <html> here. Doing so forces the root's
   overflow-y to compute as `auto`, which collapses the root scroll box
   (scrollHeight and clientHeight both report 0) and silently breaks
   window.scrollTo, scroll-linked state and scroll anchoring. */
section { overflow: hidden; }

/* ---------- 6. Mobile navigation ----------------------------------------- */
/* 21 of 22 pages hid their nav links below 840px with no hamburger and no
   drawer — the site was a navigational dead end on a phone. nfis.js injects
   the button and drawer markup; the styling lives here. */

.nfis-burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--charcoal);
}
.nfis-burger span {
  display: block;
  width: 22px;
  height: 2px;
  border-radius: 1px;
  background: currentColor;
  transition: transform var(--dur-base) var(--ease-out),
              opacity var(--dur-fast) linear;
}
.nfis-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nfis-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nfis-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.nfis-drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: .25rem;
  padding: 5.5rem 1.75rem 2rem;
  background: var(--cream);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out),
              visibility 0s linear var(--dur-base);
  overflow-y: auto;
}
.nfis-drawer.open {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}
.nfis-drawer a {
  font-family: Spectral, Georgia, serif;
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--charcoal);
  padding: .7rem 0;
  border-bottom: 1px solid var(--sage-pale);
  transition: color var(--dur-base) var(--ease-out),
              padding-left var(--dur-base) var(--ease-out);
}
.nfis-drawer a:hover,
.nfis-drawer a:focus-visible { color: var(--sage-deep); padding-left: .5rem; }

/* Staggered entrance for the drawer links — a real list, so stagger is
   legitimate here. Capped at 8 items. */
.nfis-drawer.open a {
  animation: nfis-drawer-in .45s var(--ease-out) backwards;
  animation-delay: calc(var(--i, 0) * 45ms);
}
@keyframes nfis-drawer-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

.nfis-drawer__cta {
  margin-top: 1.5rem;
  background: var(--sage);
  color: #fff !important;
  text-align: center;
  border: none !important;
  border-radius: 100px;
  padding: .9rem 1.5rem !important;
  font-family: inherit !important;
  font-size: 1rem !important;
}
.nfis-drawer__cta:hover { background: var(--sage-deep); padding-left: 1.5rem !important; }

body.nfis-menu-open { overflow: hidden; }

/* The burger lives inside <nav>, which the export pinned at z-index 200 —
   below the drawer. A child cannot escape its parent's stacking context, so
   the close (X) was buried and the only way out was Esc. Lift the whole bar
   above the drawer while the menu is open. */
body.nfis-menu-open nav { z-index: calc(var(--z-drawer) + 10) !important; }

/* Show the burger exactly where the export hides the inline links. */
@media (max-width: 840px) {
  .nfis-burger { display: flex; }

  /* The nav bar was built for a desktop row. Once the links collapse, the
     brand lockup + CTA + burger no longer fit, and the brand name wrapped to
     three lines — which in turn pushed the nav tall enough to clip the hero
     heading beneath it. Keep the bar to a single predictable row. */
  nav a[href="index.html"] > div {
    white-space: nowrap;
    font-size: 1rem !important;
    line-height: 1.2;
  }
  /* The CTA is the first item in the drawer; duplicating it in a cramped bar
     costs more than it earns. */
  nav .nfis-links + div > a[href*="Contact"] { display: none !important; }
}

/* The trust row separates its items with 4px dot spans. Measured: the row
   wraps to two lines at 768px once the dots are in play, which strands them
   at line ends — so they come out at the same breakpoint the grids collapse. */
@media (max-width: 768px) {
  [style*="width: 4px"][style*="border-radius: 50%"] { display: none !important; }
}

/* Phone. Everything that is still multi-column comes down to one. */
@media (max-width: 560px) {
  [style*="grid-template-columns: repeat(4, 1fr)"],
  [style*="grid-template-columns: 2fr 1fr 1fr 1fr"] {
    grid-template-columns: 1fr !important;
  }
}

/* Below ~380px even the shortened lockup competes with the burger. */
@media (max-width: 380px) {
  nav a[href="index.html"] > div { font-size: .9rem !important; }
  nav a[href="index.html"] img { height: 36px !important; }
}
@media (min-width: 841px) {
  .nfis-drawer { display: none; }
}

/* The phone number is hidden below 1180px by the export's own rule; surface
   it in the drawer instead (handled in nfis.js). */

/* ---------- 7. Motion / scroll reveals ----------------------------------- */
/* Content is visible by default. The hidden state applies only once nfis.js
   has confirmed IntersectionObserver support and tagged <html>, so a script
   failure or a headless render can never ship a blank page. */

/* Longhand, not the shorthand: a var() inside a shorthand becomes a
   pending-substitution value, which serialises as empty and makes this rule
   effectively undebuggable in devtools. */
html.nfis-reveal-ready .nfis-reveal {
  opacity: 0;
  transform: translateY(22px);
  transition-property: opacity, transform;
  transition-duration: var(--dur-slow);
  transition-timing-function: var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms);
  will-change: opacity, transform;
}
html.nfis-reveal-ready .nfis-reveal.in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Nav gains a surface once the page scrolls — anchors the header without a
   permanent heavy bar. */
nav {
  transition: background-color .4s var(--ease-out),
              box-shadow .4s var(--ease-out);
}
nav.nfis-scrolled {
  background: rgba(253, 249, 243, .95) !important;
  backdrop-filter: blur(16px);
  box-shadow: 0 2px 20px rgba(0, 0, 0, .06) !important;
}

/* ---------- 8. Reduced motion -------------------------------------------- */
/* Every animation needs a non-animated path. Reveals resolve to visible
   immediately; transitions collapse rather than disappear entirely so state
   changes are still perceivable. */
@media (prefers-reduced-motion: reduce) {
  html.nfis-reveal-ready .nfis-reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .nfis-drawer.open a { animation: none !important; }
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
