/* =========================================================================
   ClimateDelta — mobile + interaction layer
   Loaded AFTER each page's inline <style>, so everything here overrides it.

   Design rules this file follows:
   - Nothing that hides content is applied unless <html> has .cd-js, which an
     inline snippet in <head> sets before first paint. If the stylesheet or
     script fails, every page degrades to exactly the site it is today.
   - All motion sits behind `prefers-reduced-motion: no-preference`.
   - Colours come only from the existing custom properties, so the light and
     dark palettes both keep working untouched.

   TWO BREAKPOINTS, deliberately different:

     860px  — LAYOUT. Matches the page's own inline media query: one-column
              grids, smaller headings, tighter section padding.

    1079px  — NAVIGATION. The horizontal nav measures 988px (137 logo + 595
              links + 144 button + gaps + 64 padding). Below roughly 1004px
              including a scrollbar it overflows its own padding and the
              Request Access button runs off the right edge — exactly what a
              landscape phone hits (iPhone 14 Pro Max is 932x430). So the
              drawer takes over everywhere under 1080px, which leaves ~77px of
              slack at the switch instead of ~21px at 1024.

   Anything scoped to the nav uses 1079/1080; everything else uses 860/861.
   ========================================================================= */

:root{
  --cd-ease: cubic-bezier(.22,.61,.36,1);
  --cd-ease-out: cubic-bezier(.16,1,.3,1);
  --cd-tap: 44px;              /* WCAG 2.2 minimum target */
}

/* =========================================================================
   1. Fluid typography
   The original steps from 56px straight to 40px at 860px, which leaves the
   hero headline crowding a 360px phone. clamp() removes the cliff.
   ========================================================================= */
h1.display{ font-size:clamp(30px, 7.8vw, 56px); line-height:1.07; letter-spacing:-0.012em; }
h2.display{ font-size:clamp(22px, 4.6vw, 34px); }
.lede,
.subtitle{ font-size:clamp(16px, 3.4vw, 19px); }
.hero-copy p{ font-size:clamp(16px, 3.6vw, 19px); }
.subhead{ overflow-wrap:break-word; }

@media (max-width:860px){
  body{ font-size:16.5px; }
  .prose p{ max-width:none; }
  /* Long mono strings (index codes, coordinates) are the one real overflow
     risk on a narrow screen. */
  .mono, .readout-row, .breadcrumb{ overflow-wrap:anywhere; }
}

/* =========================================================================
   2. Scroll progress bar
   ========================================================================= */
.cd-progress{
  position:fixed; inset:0 0 auto 0; height:2px; z-index:70;
  transform:scaleX(0); transform-origin:0 50%;
  background:linear-gradient(90deg, var(--accent), var(--mark));
  pointer-events:none; will-change:transform;
}

/* =========================================================================
   3. Header: condense on scroll
   ========================================================================= */
header.nav{ transition:background .25s ease, box-shadow .25s ease; }
.nav-inner{ transition:padding .28s var(--cd-ease); }

.cd-js header.nav.cd-stuck{
  background:color-mix(in srgb, var(--bg) 97%, transparent);
  box-shadow:0 10px 30px -22px rgba(0,0,0,.75);
}
.cd-js header.nav.cd-stuck .nav-inner{ padding-top:11px; padding-bottom:11px; }

/* Desktop nav only (see the breakpoint note above): wipe underline on links. */
@media (min-width:1080px){
  nav.links > a,
  .dropdown-trigger{ position:relative; }
  nav.links > a::after,
  .dropdown-trigger::after{
    content:""; position:absolute; left:0; right:0; bottom:-6px; height:1.5px;
    background:var(--accent); transform:scaleX(0); transform-origin:100% 50%;
    transition:transform .3s var(--cd-ease);
  }
  nav.links > a:hover::after,
  nav.links > a.active::after,
  .dropdown:hover .dropdown-trigger::after,
  .dropdown.open .dropdown-trigger::after{ transform:scaleX(1); transform-origin:0 50%; }

  .dropdown-menu a{ transition:background .16s ease, color .16s ease, padding-left .2s var(--cd-ease); }
  .dropdown-menu a:hover{ padding-left:18px; }
}

/* =========================================================================
   4. Drawer navigation — every viewport under 1080px
   Replaces both the desktop overflow described above and the original
   permanently-expanded stack, which pushed the hero ~470px down a phone.
   ========================================================================= */
.cd-burger{
  display:none;
  width:var(--cd-tap); height:var(--cd-tap);
  align-items:center; justify-content:center;
  background:none; border:1px solid var(--border); border-radius:4px;
  cursor:pointer; padding:0; flex:0 0 auto; order:3;
  -webkit-tap-highlight-color:transparent;
}
.cd-burger-box{ position:relative; width:18px; height:12px; display:block; }
.cd-burger-box span{
  position:absolute; left:0; height:1.5px; width:100%; border-radius:2px;
  background:var(--text);
  transition:transform .3s var(--cd-ease), opacity .2s ease, width .3s var(--cd-ease);
}
.cd-burger-box span:nth-child(1){ top:0; }
.cd-burger-box span:nth-child(2){ top:5.25px; width:72%; }
.cd-burger-box span:nth-child(3){ top:10.5px; }
.cd-nav-open .cd-burger-box span:nth-child(1){ transform:translateY(5.25px) rotate(45deg); }
.cd-nav-open .cd-burger-box span:nth-child(2){ opacity:0; transform:translateX(-8px); }
.cd-nav-open .cd-burger-box span:nth-child(3){ transform:translateY(-5.25px) rotate(-45deg); }

.cd-scrim{
  position:fixed; inset:0; z-index:54;
  background:color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter:blur(2px);
  opacity:0; visibility:hidden; transition:opacity .3s ease, visibility .3s;
}
.cd-nav-open .cd-scrim{ opacity:1; visibility:visible; }

@media (max-width:1079px){
  /* backdrop-filter on the header would make it the containing block for the
     position:fixed drawer below, so it is dropped here and the bar goes
     opaque instead. */
  header.nav{ backdrop-filter:none; background:var(--bg); }

  /* The drawer lives inside header.nav, so it is trapped in that element's
     stacking context (position:sticky + z-index:50). Without this the scrim —
     a body-level sibling at z-index 54 — paints over the drawer. */
  .cd-js.cd-nav-open header.nav{ z-index:56; }

  /* The open drawer overlaps the button that closes it, so lift the burger
     above it inside the header's stacking context. */
  .cd-js .cd-burger{ display:flex; position:relative; z-index:57; }

  .cd-js .nav-inner{
    flex-wrap:nowrap; row-gap:0; gap:10px;
    padding:12px 20px;
  }
  .cd-js .nav-inner > .btn{ order:2; }
  .cd-js .logo{ order:1; margin-right:auto; }

  .cd-js nav.links{
    position:fixed; top:0; right:0; bottom:0; left:auto;
    width:min(87vw, 370px);
    order:0;
    display:flex; flex-direction:column; align-items:stretch; gap:0;
    padding:88px 22px 48px;
    background:var(--surface);
    border-left:1px solid var(--border);
    box-shadow:var(--shadow);
    overflow-y:auto; overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch;
    z-index:55;
    transform:translateX(101%);
    visibility:hidden;
    transition:transform .4s var(--cd-ease-out), visibility .4s;
  }
  .cd-js.cd-nav-open nav.links{ transform:none; visibility:visible; }

  /* Top-level rows: real 52px targets, not 13px text. */
  .cd-js nav.links > a,
  .cd-js nav.links .dropdown-trigger{
    display:flex; align-items:center; justify-content:space-between;
    width:100%; min-height:52px; padding:0;
    font-size:16px; font-weight:500; color:var(--text);
    border-bottom:1px solid var(--border);
    text-align:left;
  }
  .cd-js nav.links > a.active{ color:var(--accent); }
  .cd-js nav.links .dropdown{ width:100%; border:0; position:static; }
  .cd-js nav.links .caret{
    font-size:11px; color:var(--text-muted);
    transition:transform .3s var(--cd-ease);
  }
  .cd-js nav.links .dropdown.open .caret{ transform:rotate(180deg); color:var(--accent); }

  /* Between 861 and 1079 the page's own stylesheet still applies its desktop
     `.dropdown:hover` rules, which would rotate the caret and float the menu
     over the page on hover inside the drawer. The next two rules neutralise
     that, so the accordion is driven only by .open. */
  .cd-js nav.links .dropdown:not(.open) .caret{ transform:none; }
  .cd-js nav.links .dropdown-menu{
    position:static; left:auto; top:auto;
    transform:none !important;
    opacity:1; visibility:visible;
    min-width:0; width:100%;
    max-height:0; overflow:hidden; padding:0;
    border:none; border-left:1px solid var(--border); box-shadow:none;
    margin-left:2px;
    transition:max-height .34s var(--cd-ease);
  }
  .cd-js nav.links .dropdown.open .dropdown-menu{
    max-height:520px; padding:4px 0 12px;
    border-left-color:var(--accent);
  }
  .cd-js nav.links .dropdown-menu a{
    display:flex; align-items:center; min-height:46px;
    padding:0 0 0 16px; font-size:15px; color:var(--text-muted);
    border-radius:0;
  }
  .cd-js nav.links .dropdown-menu a:active{ color:var(--text); }

  /* Staggered entrance for the drawer rows. */
  @media (prefers-reduced-motion:no-preference){
    .cd-js.cd-nav-open nav.links > *{
      animation:cd-drawer-item .45s var(--cd-ease-out) backwards;
      animation-delay:calc(var(--cd-i, 0) * 42ms + 90ms);
    }
  }
}
@keyframes cd-drawer-item{
  from{ opacity:0; transform:translateX(24px); }
  to  { opacity:1; transform:none; }
}

/* The header button only needs to shrink once space is genuinely tight. */
@media (max-width:860px){
  .cd-js .nav-inner > .btn{ font-size:13px; padding:9px 14px; }
}

/* Small phones: logo + Request Access + burger together need 321px of the
   320px available at 360px wide, which pushes the burger past the padding.
   Reclaim ~25px so the burger keeps a real edge margin. */
@media (max-width:400px){
  .cd-js .nav-inner{ padding-left:14px; padding-right:14px; gap:8px; }
  .cd-js .nav-inner > .btn{ font-size:12px; padding:9px 11px; letter-spacing:0; }
  .cd-js .logo{ font-size:13px; letter-spacing:0.05em; }
}

/* =========================================================================
   5. Tap targets
   33 of the 36 links on the homepage were under 44px tall.
   ========================================================================= */
/* Target SIZE follows the input device, not the viewport width: a landscape
   phone is 932px wide but still operated with a thumb, and keying this to the
   860px layout breakpoint left 26 links under 44px there. The orientation
   clause is the deterministic half (short + landscape == a phone on its side);
   pointer:coarse catches tablets and touch laptops too. */
@media (max-width:860px),
       (pointer:coarse),
       ((max-height:500px) and (orientation:landscape)){
  .btn, .btn-ghost{
    min-height:var(--cd-tap);
    display:inline-flex; align-items:center; justify-content:center;
  }
  .breadcrumb a{ display:inline-flex; align-items:center; min-height:var(--cd-tap); }
  .logo{ min-height:var(--cd-tap); }
  footer .foot-inner a{ display:inline-flex; align-items:center; min-height:var(--cd-tap); }
}

/* Stacking things into a single column, by contrast, is purely about width. */
@media (max-width:860px){
  .hero-actions{ flex-direction:column; align-items:stretch; gap:10px; }
  .hero-actions .btn,
  .hero-actions .btn-ghost{ width:100%; }
  .cta-actions{ flex-direction:column; align-items:flex-start; gap:12px; }
  .cta-actions .btn{ width:100%; }
  .drill-next{ display:flex; flex-direction:column; align-items:flex-start; gap:10px; }
  .drill-next .btn-ghost{ width:100%; }
}

/* =========================================================================
   6. Scroll reveal
   Gated on .cd-js so a script failure never leaves the page blank.
   ========================================================================= */
@media (prefers-reduced-motion:no-preference){
  .cd-js .cd-reveal{
    opacity:0;
    transform:translateY(12px);
    transition:opacity .42s var(--cd-ease-out), transform .42s var(--cd-ease-out);
    transition-delay:var(--cd-delay, 0ms);
  }
  .cd-js .cd-reveal.cd-in{ opacity:1; transform:none; }
}

/* =========================================================================
   7. Content micro-interactions
   ========================================================================= */

/* Ledger / workflow / foundry rows: an accent rail wipes in on hover & tap. */
.ledger-row,
.wf-row,
.foundry-row{
  position:relative;
  transition:background .25s ease, transform .25s var(--cd-ease);
}
.ledger-row::before,
.wf-row::before,
.foundry-row::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:2px;
  background:var(--accent); transform:scaleY(0); transform-origin:50% 0;
  transition:transform .3s var(--cd-ease);
}
.ledger-row:hover::before,
.wf-row:hover::before,
.foundry-row:hover::before,
.ledger-row:active::before,
.wf-row:active::before,
.foundry-row:active::before{ transform:scaleY(1); }

@media (hover:hover){
  .ledger-row:hover,
  .wf-row:hover,
  .foundry-row:hover{
    background:color-mix(in srgb, var(--surface) 60%, transparent);
  }
  .ledger-row:hover .name,
  .foundry-row:hover .name{ color:var(--accent); }
}
.ledger-row .name,
.foundry-row .name{ transition:color .25s ease; }

@media (max-width:860px){
  /* Only index.html's own media query collapses these to one column; the
     interior pages keep the desktop two-column grid, which squeezes the
     description into ~62px and overflows the viewport on the longer pages. */
  .ledger-row,
  .wf-row{ grid-template-columns:1fr; gap:6px; }

  .ledger-row,
  .wf-row,
  .foundry-row{ padding-left:14px; }
  .ledger-row::before,
  .wf-row::before,
  .foundry-row::before{ transform:scaleY(1); opacity:.28; }
  .ledger-row:active::before{ opacity:1; }
}

/* Buttons: real press feedback, which touch devices otherwise never get. */
.btn, .btn-ghost{
  transition:opacity .15s ease, transform .15s var(--cd-ease),
             border-color .2s ease, background .2s ease;
  -webkit-tap-highlight-color:transparent;
}
.btn:active, .btn-ghost:active{ transform:scale(.97); }
@media (hover:hover){
  .btn-ghost:hover{ background:color-mix(in srgb, var(--accent) 12%, transparent); }
}

/* Cards lift slightly. */
.readout, .chart-card, .callout, .pullquote, .refrain-box{
  transition:transform .35s var(--cd-ease), box-shadow .35s var(--cd-ease);
}
@media (hover:hover){
  .readout:hover, .chart-card:hover{ transform:translateY(-3px); }
}

/* Hero readout rows cascade in behind the card itself. */
@media (prefers-reduced-motion:no-preference){
  .cd-js .readout.cd-in .readout-row,
  .cd-js .readout.cd-in .readout-status{
    animation:cd-row-in .5s var(--cd-ease-out) backwards;
    animation-delay:calc(var(--cd-i, 0) * 70ms + 180ms);
  }
  .cd-js .readout.cd-in .readout-status .tag{
    animation:cd-pulse 2.4s ease-in-out 1.4s infinite;
  }
}
@keyframes cd-row-in{
  from{ opacity:0; transform:translateY(8px); }
  to  { opacity:1; transform:none; }
}
@keyframes cd-pulse{
  0%,100%{ opacity:1; }
  50%    { opacity:.55; }
}

/* The proof chart draws itself once it scrolls into view. */
@media (prefers-reduced-motion:no-preference){
  .cd-js .chart .index-line{
    stroke-dasharray:var(--cd-len, 600);
    stroke-dashoffset:var(--cd-len, 600);
  }
  .cd-js .chart.cd-in .index-line{
    transition:stroke-dashoffset 1.8s var(--cd-ease-out) .25s;
    stroke-dashoffset:0;
  }
  .cd-js .chart .mark-dot,
  .cd-js .chart .mark-label,
  .cd-js .chart .threshold-line{ opacity:0; }
  .cd-js .chart.cd-in .mark-dot,
  .cd-js .chart.cd-in .mark-label{ transition:opacity .5s ease 1.5s; opacity:1; }
  .cd-js .chart.cd-in .threshold-line{ transition:opacity .6s ease .1s; opacity:1; }
}

/* Prose links get a proper underline animation. */
.prose p a:not(.btn):not(.btn-ghost){
  text-decoration:none;
  background-image:linear-gradient(var(--accent), var(--accent));
  background-size:0% 1px; background-position:0 100%; background-repeat:no-repeat;
  transition:background-size .3s var(--cd-ease);
  color:var(--accent);
}
.prose p a:not(.btn):not(.btn-ghost):hover{ background-size:100% 1px; }

/* =========================================================================
   8. Back to top
   ========================================================================= */
.cd-top{
  position:fixed; right:18px; bottom:18px; z-index:45;
  width:46px; height:46px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:var(--surface); color:var(--text);
  border:1px solid var(--border); box-shadow:var(--shadow);
  cursor:pointer; padding:0;
  opacity:0; visibility:hidden; transform:translateY(12px) scale(.9);
  transition:opacity .3s ease, transform .3s var(--cd-ease-out), visibility .3s,
             border-color .2s ease;
  -webkit-tap-highlight-color:transparent;
}
.cd-top.cd-show{ opacity:1; visibility:visible; transform:none; }
.cd-top:hover{ border-color:var(--accent); color:var(--accent); }
.cd-top:active{ transform:scale(.92); }
.cd-top svg{ width:16px; height:16px; }
.cd-nav-open .cd-top{ opacity:0; visibility:hidden; }

@media (max-width:860px){
  .cd-top{ right:14px; bottom:14px; }
}

/* =========================================================================
   9. Misc mobile layout repairs
   ========================================================================= */
@media (max-width:860px){
  section{ padding:52px 0; }
  .hero{ padding-top:36px; padding-bottom:40px; }
  .hero-grid{ gap:32px; }
  .hero-block{ padding-top:36px; }
  .readout{ padding:18px 16px; }
  .readout-row{ font-size:12px; gap:10px; }
  .workflow-table, .foundry-table{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .signatures{ flex-wrap:wrap; }
}

/* Landscape phones are wide but only ~430px tall: reclaim vertical space and
   keep the drawer usable when its rows are taller than the screen. */
@media (max-height:500px) and (orientation:landscape){
  section{ padding:44px 0; }
  .hero{ padding-top:28px; padding-bottom:32px; }
  .cd-js nav.links{ padding-top:74px; padding-bottom:28px; }
  .cd-js nav.links > a,
  .cd-js nav.links .dropdown-trigger{ min-height:46px; }
  /* Never below --cd-tap: the drawer scrolls, so trimming rows here would buy
     a little height at the cost of the 44px minimum. */
  .cd-js nav.links .dropdown-menu a{ min-height:var(--cd-tap); }
}

/* Anchored sections must clear the sticky header. */
:target,
section[id],
main[id]{ scroll-margin-top:84px; }

/* Honour the OS setting globally. */
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
}
