/* Conifer Technologies — Shared Design System */

:root {
  --green: #153D26;
  --green-deep: #0E2A1A;
  --black: #0A0A0A;
  --white: #FFFFFF;
  --sage: #9FA582;
  --sage-quiet: rgba(159, 165, 130, 0.25);
  --sage-line: rgba(159, 165, 130, 0.35);
  --font-display: 'Cormorant Garamond', Georgia, serif;
  --font-sans: 'Manrope', -apple-system, sans-serif;

  /* ----- LAYOUT ----- */
  /* --gutter is the responsive side margin. --bleed adds whatever extra is
     needed to centre content at --content-max, so section backgrounds stay
     full-bleed while their contents stay contained.

     IMPORTANT: the 100% in --bleed resolves against the element's containing
     block, so --bleed is only correct in padding-inline on a direct child of
     <body>. Anything nested (an absolutely positioned rule inside an
     already-gutter-subtracted section, say) must use --gutter instead. */
  --gutter: clamp(20px, 5vw, 64px);
  --content-max: 1560px;
  --bleed: max(var(--gutter), calc((100% - var(--content-max)) / 2));
  /* approximate rendered bar height; the real bar is ~73px desktop / ~76px in
     the mobile panel. Consumers add their own margin on top of this. */
  --nav-h: 72px;

  /* ----- FLUID TYPE SCALE ----- */
  /* Two-anchor clamps: minimum at a 375px viewport, maximum at --content-max
     (1560px), so type stops growing exactly where the layout stops growing.
     The rem term (not vw alone) is what keeps these responsive to the user's
     browser font-size preference. Every max below equals the previous fixed
     desktop size, so desktop rendering is unchanged. */
  --fs-stat: clamp(56px, 2.55rem + 4.05vw, 104px);
  --fs-d1:   clamp(42px, 1.72rem + 3.88vw, 88px);
  --fs-d2:   clamp(38px, 1.54rem + 3.54vw, 80px);
  --fs-d3:   clamp(34px, 1.45rem + 2.87vw, 68px);
  --fs-d4:   clamp(34px, 1.53rem + 2.53vw, 64px);
  --fs-d5:   clamp(32px, 1.45rem + 2.36vw, 60px);
  --fs-d6:   clamp(30px, 1.40rem + 2.03vw, 54px);
  --fs-d7:   clamp(30px, 1.44rem + 1.86vw, 52px);
  --fs-d8:   clamp(28px, 1.35rem + 1.69vw, 48px);
  --fs-d9:   clamp(28px, 1.43rem + 1.35vw, 44px);
  --fs-d10:  clamp(26px, 1.39rem + 1.01vw, 38px);
  --fs-d11:  clamp(24px, 1.38rem + 0.51vw, 30px);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
/* 100% (not a fixed px) so the browser's font-size preference is honoured.
   Visually identical at default settings, since the scale above is px-anchored. */
html { font-size: 100%; }

/* Responsive safety net. max-width only — several scoped rules rely on fixed
   heights, so no global height:auto. overflow-wrap:break-word does not affect
   min-content sizing, so it only engages on genuine overflow. */
img, svg, video, iframe, canvas { max-width: 100%; }
body { overflow-wrap: break-word; }
body {
  font-family: var(--font-sans);
  font-weight: 300;
  color: var(--black);
  background: var(--white);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Offset anchor jumps so targets clear the fixed nav */
:target { scroll-margin-top: calc(var(--nav-h) + 36px); }

.eyebrow {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--sage);
}

/* ----- NAV ----- */
/* Transparent at the top of the page; turns solid green after significant
   scroll (the .scrolled class is toggled by include-partials.js).
   Pages with a light/white hero add .nav-light-top so the nav uses dark
   text and the dark logo until it turns green. */
nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  padding: 16px var(--bleed);
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 100;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color 0.4s ease, border-color 0.4s ease;
}
nav.scrolled {
  background: var(--green);
  border-bottom-color: rgba(255,255,255,0.08);
}
.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  color: var(--white);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 28px;
  letter-spacing: 0.02em;
}
.logo img.logo-mark { display: block; height: 1.1em; width: auto; }
.logo img.logo-dark { display: none; }
.logo .mark { color: var(--sage); margin-right: 6px; }
.nav-links { display: flex; gap: 44px; align-items: center; }
.nav-links a {
  font-size: 13px;
  font-weight: 400;
  color: var(--white);
  text-decoration: none;
  letter-spacing: 0.02em;
  transition: color 0.3s ease, border-color 0.3s ease;
}
.nav-links a.active:not(.nav-cta) {
  color: var(--sage);
  border-bottom: 1px solid var(--sage);
  padding-bottom: 4px;
}
/* animated hover underline on the section links (not the Inquire button) */
.nav-links a:not(.nav-cta):not(.active) { position: relative; }
.nav-links a:not(.nav-cta):not(.active)::after {
  content: '';
  position: absolute;
  left: 0; bottom: -4px;
  width: 100%; height: 1px;
  background: var(--sage);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.nav-links a:not(.nav-cta):not(.active):hover::after { transform: scaleX(1); }
.nav-cta {
  padding: 10px 22px;
  border: 1px solid rgba(255,255,255,0.4);
  border-radius: 1px;
  font-size: 12px !important;
  letter-spacing: 0.05em;
  color: var(--white) !important;
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), color 0.25s ease, border-color 0.25s ease;
}
.nav-cta:hover { transform: translateY(-2px); border-color: var(--white); }
.nav-cta:active { transform: translateY(0); }

/* Light-hero pages: dark nav (and dark logo) until scrolled.
   Every rule is also gated on :not(.nav-open) — the mobile panel is always a
   dark green surface, so the whole light-hero treatment has to switch off
   while it's up. Gating here rather than overriding below matters: these
   selectors carry an extra :not(), which made them out-specify the open-state
   overrides and leave the current page's link dark-on-dark (invisible). */
nav.nav-light-top:not(.scrolled):not(.nav-open) .logo-light { display: none; }
nav.nav-light-top:not(.scrolled):not(.nav-open) .logo-dark { display: block; }
nav.nav-light-top:not(.scrolled):not(.nav-open) .nav-links a { color: var(--black); }
nav.nav-light-top:not(.scrolled):not(.nav-open) .nav-links a.active:not(.nav-cta) {
  color: var(--green);
  border-bottom-color: var(--green);
}
nav.nav-light-top:not(.scrolled):not(.nav-open) .nav-cta {
  border-color: rgba(21, 61, 38, 0.4);
  color: var(--green) !important;
}
nav.nav-light-top:not(.scrolled):not(.nav-open) .nav-cta:hover { border-color: var(--green); }
nav.nav-light-top:not(.scrolled):not(.nav-open) .nav-links a:not(.nav-cta):not(.active)::after { background: var(--green); }

@media (prefers-reduced-motion: reduce) {
  .nav-cta { transition: color 0.3s ease, border-color 0.3s ease; }
  .nav-cta:hover { transform: none; }
  .nav-links a:not(.nav-cta):not(.active)::after { transition: none; }
}

/* ----- MOBILE NAV ----- */
/* Toggle is hidden above the nav breakpoint. The open panel is always a dark
   green surface, so nothing down here needs a light-hero variant: the
   .nav-light-top rules above exclude .nav-open themselves, which leaves the
   dark-background defaults in force. Don't reintroduce open-state overrides
   scoped to .nav-light-top — those selectors carry extra :not() arguments that
   count toward specificity, so an override would lose to them. */
.nav-toggle {
  display: none;
  position: relative;
  z-index: 1;
  width: 44px;
  height: 44px;
  margin-right: -10px;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
}
.nav-toggle-bar {
  display: block;
  width: 26px;
  height: 1px;
  background: var(--white);
  transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1);
}
.nav-toggle-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* locked by the toggle JS so the page can't scroll behind the open panel */
body.nav-lock { overflow: hidden; }

/* Hamburger takes over at the content tier (768px) so tablet portrait gets the
   full-size panel tap targets instead of the cramped inline links. */
@media (max-width: 768px) {
  .nav-toggle { display: flex; }
  .logo { position: relative; z-index: 1; }

  .nav-links {
    position: fixed;
    inset: 0;
    padding: calc(var(--nav-h) + 32px) var(--gutter) 40px;
    background: var(--green);
    flex-direction: column;
    align-items: flex-start;
    /* Deliberately NOT justify-content:center. When the list is taller than the
       panel, centring overflows equally in BOTH directions, pushing the first
       link up under the logo where it can't be tapped and can't be scrolled to
       (small phone in landscape, or a large accessibility font size). The auto
       margins below centre the group when there is room and collapse to 0 when
       there isn't, so the list just starts below the bar and scrolls. */
    justify-content: flex-start;
    gap: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    /* visibility rather than display: keeps the fade AND takes the links out
       of the tab order while closed */
    visibility: hidden;
    opacity: 0;
    transition: opacity 0.28s ease, visibility 0s linear 0.28s;
  }
  .nav-links > :first-child { margin-top: auto; }
  .nav-links > :last-child { margin-bottom: auto; }
  nav.nav-open .nav-links {
    visibility: visible;
    opacity: 1;
    transition: opacity 0.28s ease, visibility 0s linear 0s;
  }

  /* All four entries render identically here: big serif links on hairlines.
     No :not(.nav-cta) — the CTA is meant to pick these up. */
  .nav-links a {
    width: 100%;
    padding: 18px 0;
    font-family: var(--font-display);
    font-weight: 300;
    font-size: 32px;
    color: var(--white);
    border-bottom: 1px solid var(--sage-quiet);
  }
  /* Inquire is a plain fourth link in the panel, not a button, so strip the
     ghost-button chrome the desktop rule gives it. The rule above wins on
     specificity (0,1,1 vs 0,1,0) for padding/font/colour, but the base
     .nav-cta's own !important font-size has to be beaten with !important. */
  .nav-cta {
    margin-top: 0;
    border: none;
    border-radius: 0;
    letter-spacing: 0;
    text-align: left;
    font-size: 32px !important;
  }
  /* it's not a button here, so drop the button's hover lift (which can stick
     after a tap on touch) */
  .nav-cta:hover,
  .nav-cta:active { transform: none; }
  /* a full-width underline would read as a divider, so active is colour only */
  .nav-links a.active {
    color: var(--sage);
    border-bottom-color: var(--sage-quiet);
    padding-bottom: 18px;
  }
  .nav-cta.active { color: var(--sage) !important; }
  .nav-links a:not(.nav-cta):not(.active)::after { display: none; }

  /* One hover/focus treatment for all four entries. The desktop underline
     sweep is disabled in this panel, so the section links would otherwise have
     no feedback at all, while the CTA kept the button's border brighten — which
     is why only Inquire appeared to respond. The CTA needs !important on colour
     to beat the base .nav-cta rule. */
  .nav-links a:hover,
  .nav-links a:focus-visible {
    color: var(--sage);
    border-bottom-color: var(--sage);
  }
  .nav-cta:hover,
  .nav-cta:focus-visible { color: var(--sage) !important; }

  /* hamburger reads dark over a light hero, white once the green panel is up
     (the :not(.nav-open) hands it back to the base white bar) */
  nav.nav-light-top:not(.scrolled):not(.nav-open) .nav-toggle-bar { background: var(--black); }

  nav.nav-open .nav-toggle-bar:nth-child(1) { transform: translateY(4px) rotate(45deg); }
  nav.nav-open .nav-toggle-bar:nth-child(2) { transform: translateY(-4px) rotate(-45deg); }

  /* the bar must go solid even at scroll-0, or page content shows through it */
  nav.nav-open { background: var(--green); border-bottom-color: transparent; }

  /* No light-hero overrides needed here: the .nav-light-top block above opts
     itself out via :not(.nav-open), so an open panel falls through to the
     dark-background defaults (white logo, white bars, white links, sage
     active/hover) on every page regardless of what the hero looks like. */
}

/* Short viewport (small phone in landscape, or a bumped accessibility font):
   shrink the list so it still fits without needing to scroll. */
@media (max-width: 768px) and (max-height: 480px) {
  .nav-links {
    padding-top: calc(var(--nav-h) + 16px);
    padding-bottom: 24px;
  }
  .nav-links a { padding: 11px 0; font-size: 24px; }
  .nav-links a.active { padding-bottom: 11px; }
  .nav-cta { font-size: 24px !important; }
}

@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
  .nav-links,
  nav.nav-open .nav-links,
  .nav-toggle-bar { transition: none; }
}

/* ----- CTA BLOCK ----- */
.cta-block {
  padding: 140px var(--bleed);
  text-align: center;
  color: var(--white);
}
.cta-block .eyebrow { color: var(--sage); margin-bottom: 32px; }
.cta-block h2 {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--fs-d5);
  line-height: 1.08;
  letter-spacing: -0.01em;
  margin-bottom: 48px;
  max-width: 800px;
  margin-left: auto;
  margin-right: auto;
}
.cta-block h2 em { color: var(--sage); font-style: italic; }
.cta-btn {
  display: inline-block;
  padding: 18px 44px;
  border: 1px solid var(--sage);
  color: var(--white);
  text-decoration: none;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 500;
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.25s ease;
}
.cta-btn:hover {
  transform: translateY(-2px);
  border-color: var(--white);
}
.cta-btn:active { transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .cta-btn { transition: border-color 0.25s ease; }
  .cta-btn:hover, .cta-btn:active { transform: none; }
}

/* ----- FOOTER ----- */
footer {
  background: var(--black);
  color: rgba(255,255,255,0.6);
  padding: 80px var(--bleed) 40px;
}
.footer-top {
  display: grid;
  /* minmax(0,…) rather than bare fr: an auto minimum lets an unbreakable token
     (the contact email) blow the track out and push the whole document sideways. */
  grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
  gap: 48px;
  padding-bottom: 64px;
  border-bottom: 1px solid rgba(159, 165, 130, 0.15);
}
footer .logo { color: var(--white); }
.footer-tag {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.6);
  margin-top: 18px;
  max-width: 300px;
  line-height: 1.6;
}
.footer-col h5 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--sage);
  margin-bottom: 20px;
  font-weight: 500;
}
.footer-col a {
  display: block;
  color: rgba(255,255,255,0.65);
  text-decoration: none;
  font-size: 14px;
  margin-bottom: 10px;
  /* the contact email is one long unbreakable token; let it wrap rather than
     widen its grid track */
  overflow-wrap: anywhere;
}
.footer-bottom {
  padding-top: 32px;
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: rgba(255,255,255,0.4);
}

/* ----- SHARED RESPONSIVE TIERS ----- */
/* Tablet: the four footer columns stop fitting, so the brand block takes its
   own row and the three link columns share the next one. */
@media (max-width: 1024px) {
  .footer-top {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 40px;
  }
  .footer-top > :first-child { grid-column: 1 / -1; }
  .footer-col a { padding: 8px 0; }
}

@media (max-width: 768px) {
  .cta-block { padding: 90px var(--gutter); }
  .cta-block h2 { line-height: 1.14; margin-bottom: 36px; }
  .cta-btn { padding: 16px 32px; }

  footer { padding: 64px var(--gutter) 32px; }
  .footer-top {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 36px;
    padding-bottom: 48px;
  }
  /* brand and Contact span the full width; Contact holds the long email */
  .footer-top > :first-child,
  .footer-top > :last-child { grid-column: 1 / -1; }
  .footer-col a { padding: 11px 0; margin-bottom: 2px; } /* ~44px tap target */
  .footer-bottom { flex-wrap: wrap; gap: 10px; }
}

/* Buttons/chips lift on :hover; on touch, :hover sticks after a tap (until the
   next tap elsewhere), leaving them stuck in the lifted state. Neutralise the
   lift on touch pointers. !important because most of these are styled in
   per-page inline <style> that loads after this file. */
@media (hover: none) {
  .cta-btn:hover,
  .nav-cta:hover,
  .work-all-link:hover,
  .founders a:hover,
  .chip:hover,
  .submit:hover,
  .back-link:hover,
  .case-next-btn:hover,
  .case-not-found a:hover,
  .engagement-card:hover { transform: none !important; }
}

/* ----- CASE MEDIA FALLBACK ----- */
/* Built by caseImgError() in src/work/cases.js. When a case hero/thumb photo
   is missing, the client logo is shown on a light card; if the logo is
   unavailable too, the client name is shown. Fills its (relatively or
   absolutely positioned) media container on the home, work, and case pages. */
.media-logo-host {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #FAF9F5;
}
/* two classes beat the per-page `.case-media img` / `.case-hero-img img` rules */
.media-logo-host .media-logo {
  width: auto;
  height: auto;
  max-width: 48%;
  max-height: 46%;
  object-fit: contain;
}
.media-logo-host .media-fallback {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  color: var(--sage);
  font-size: 24px;
  text-align: center;
  padding: 0 24px;
}
