/* Footer: a full-screen end scene. The logo pile is its background (two canvases, edge to edge, behind the content), the call to
   action sits on top, the link columns in the middle, the legal row at the bottom. One footer for every page.
   Markup lives in each page (and scripts/lib/projects-shell.mjs for the generated pages); js/footer-pile.js fills the pile, splits the
   headline and the .f-r labels, and toggles .is-in for the entrance. Colours are the Astro tokens only. Motion is transform and
   opacity only, on the site's three easings (expoOut, the strong ease-out, expoInOut). */
:root { --x-out: cubic-bezier(.16, 1, .3, 1); --x-p: cubic-bezier(.35, 0, 0, 1); --x-io: cubic-bezier(.87, 0, .13, 1); --x-letter: .667s; --x-row: .9s; --x-line: 1s; }
@media (max-width: 700px) { :root { --x-letter: .5s; --x-row: .6s; --x-line: .7s; } }

footer.foot { position: relative; z-index: 1; display: flex; flex-direction: column; min-height: 100vh; min-height: 100svh; padding: 0; border-top: 1px solid var(--line);
  background: var(--bg); overflow: hidden; isolation: isolate;
  touch-action: pan-y; -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
@media (max-width: 700px) { footer.foot { min-height: 100vh; min-height: 100dvh; } }
.foot-ripple { position: absolute; z-index: 0; border: 1px solid var(--accent); border-radius: 50%; pointer-events: none; opacity: 0; will-change: transform, opacity; }

/* ---- the pile: one layer behind the content, drawn at reduced opacity. The content layer lets the pointer through (only links and
   buttons take it), so marks can be pushed and dragged from anywhere while every link stays clickable and keyboard reachable. */
.foot-pile { position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: .45; contain: layout paint; }
.foot-pile canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

.foot-in { position: relative; z-index: 1; flex: 1 1 auto; display: flex; flex-direction: column; padding: clamp(96px, 15vh, 150px) 4vw var(--s3);
  text-align: left; pointer-events: none; text-shadow: 0 0 10px var(--bg), 0 0 22px var(--bg); }
.foot-in a, .foot-in button { pointer-events: auto; cursor: pointer; }
.foot-in .a-btn { text-shadow: none; }

/* ---- call to action */
.foot-top { position: relative; display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s4) var(--s5); padding-bottom: var(--s5); }
.foot-top::after, .foot-legal::before { content: ''; position: absolute; left: 0; right: 0; height: 1px; background: var(--line); transform-origin: left center; }
.foot-top::after { bottom: 0; }
.foot-legal::before { top: 0; }
.foot-big { flex: 1 1 18ch; min-width: 0; margin: 0; font: 200 clamp(32px, 6vw, 96px)/1.06 var(--font-display); letter-spacing: .08em; text-transform: uppercase; color: var(--ink); }
.f-W { display: inline-block; white-space: nowrap; }
.f-L { display: inline-block; }
.foot-cta { gap: 14px; transform: translate3d(var(--mx, 0px), var(--my, 0px), 0); }
.foot-cta:active { transform: translate3d(var(--mx, 0px), var(--my, 0px), 0) scale(.98); }

/* ---- link columns */
.foot-grid { display: grid; grid-template-columns: 1.5fr repeat(3, minmax(0, 1fr)); gap: var(--s5) var(--s4); padding: var(--s5) 0; margin-block: auto; }
.foot-brand { min-width: 0; }
.foot-logo { display: inline-flex; align-items: center; min-height: 44px; }
.foot-logo img { display: block; width: 92px; height: auto; transform-origin: 0 50%; }
.foot-line { width: fit-content; margin: var(--s2) 0 4px; font: 200 clamp(20px, 1.9vw, 28px)/1.2 var(--font-display); letter-spacing: .08em; text-transform: uppercase; color: var(--ink); }
.foot-fr { width: fit-content; margin: 0 0 var(--s3); font: 300 12px/1.6 var(--font-display); letter-spacing: .3em; text-transform: uppercase; color: var(--soft); }
.foot-brand .cap { width: fit-content; margin: 0; color: var(--soft); }
.foot-col { min-width: 0; }
.foot-h { width: fit-content; margin: 0 0 var(--s2); color: var(--soft); }
.foot-col ul, .foot-legal ul { list-style: none; margin: 0; padding: 0; }
.foot-col li { margin: 0; clip-path: inset(0 -12px); }
.foot-col--site ul { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s3); }

footer.foot a { text-decoration: none; }
footer.foot a:focus-visible, footer.foot .foot-pause:focus-visible { outline: 2px solid var(--ink); outline-offset: -3px; }
.foot-col a { position: relative; display: inline-flex; align-items: center; gap: 10px; min-height: 44px; font: 300 13px/1.35 var(--font-display); letter-spacing: .16em; text-transform: uppercase; color: var(--accent);
  overflow-wrap: anywhere; transition: color var(--t-ctl) var(--ease), transform .35s var(--x-p); }
.foot-col a.foot-mail { text-transform: none; letter-spacing: .06em; }
.foot-col a:hover, .foot-col a:focus-visible { color: var(--ink); }
.foot-col .ig { width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.4; color: var(--accent); transition: transform .5s var(--x-out); }
.foot-col a .h { text-transform: none; letter-spacing: .08em; font-size: 13px; }

/* ---- legal row */
.foot-legal { position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s1) var(--s4); padding-top: var(--s3); margin-top: auto; }
.foot-legal p { width: fit-content; margin: 0; color: var(--soft); }
.foot-legal ul { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--s4); }
.foot-legal li { clip-path: inset(0 -12px); }
.foot-legal a, .foot-legal .foot-pause { position: relative; display: inline-flex; align-items: center; gap: 10px; min-height: 44px; font: 300 11px/1.6 var(--font-display); letter-spacing: .24em; text-transform: uppercase; color: var(--soft);
  transition: color var(--t-ctl) var(--ease), transform .35s var(--x-p); }
.foot-legal .foot-pause { text-decoration: none; }
.foot-legal a:hover, .foot-legal a:focus-visible, .foot-legal .foot-pause:hover, .foot-legal .foot-pause:focus-visible { color: var(--ink); }
.foot-legal .foot-pause[hidden], .foot-legal li[hidden] { display: none; }

/* icons that roll: two copies in a clipped box, the hover slides them one step */
.ico { position: relative; display: inline-block; flex: none; width: 14px; height: 14px; overflow: hidden; }
.ico svg { position: absolute; inset: 0; width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.5; transition: transform .45s var(--x-p); }
.ico-y svg:last-child { transform: translate3d(0, 110%, 0); }
.ico-x svg:last-child { transform: translate3d(-110%, 0, 0); }

/* underline scale-in */
.foot-col a::after, .foot-legal a:not(.foot-up)::after { content: ''; position: absolute; left: 0; right: 0; bottom: 9px; height: 1px; background: currentColor; opacity: .7;
  transform: scaleX(0); transform-origin: right center; transition: transform .45s var(--x-p); }
.foot-col a:hover::after, .foot-col a:focus-visible::after, .foot-legal a:hover::after, .foot-legal a:focus-visible::after { transform: scaleX(1); transform-origin: left center; }

/* ---- char-roll (js/footer-pile.js): the label is split into columns of two stacked copies, a hover slides each by one line */
.f-roll { display: inline-flex; height: 1.35em; overflow: hidden; vertical-align: top; }
.f-ch { display: inline-block; height: 1.35em; overflow: hidden; }
.f-ch--sp { width: .32em; }
.f-ch > i { display: flex; flex-direction: column; font-style: normal; transition: transform .45s var(--x-p) calc(var(--i, 0) * 18ms); }
.f-ch > i > b { display: block; height: 1.35em; font-weight: inherit; line-height: 1.35; }
.foot-cta .lbl { display: inline-flex; }

@media (hover: hover) and (pointer: fine) {
  .foot a:hover .f-ch > i, .foot .foot-pause:hover .f-ch > i { transform: translateY(-50%); }
  .foot-col a:hover, .foot-legal a:hover { transform: translate3d(0, -2px, 0); }   /* the hovered row lifts a hair */
  .foot-col a:hover .ig { transform: rotate(-14deg) scale(1.12); }
  .foot a:hover .ico-y svg:first-child { transform: translate3d(0, -110%, 0); }
  .foot a:hover .ico-x svg:first-child { transform: translate3d(110%, 0, 0); }
  .foot a:hover .ico-y svg:last-child, .foot a:hover .ico-x svg:last-child { transform: none; }
}
.foot a:focus-visible .f-ch > i { transform: translateY(-50%); }

@media (max-width: 900px) {
  .foot-grid { grid-template-columns: 1fr 1fr; }
  .foot-brand { grid-column: 1 / -1; }
}
@media (max-width: 760px) {
  .foot-in { padding: clamp(84px, 13vh, 120px) 5vw var(--s3); }
  .foot-top { padding-bottom: var(--s4); }
  .foot-grid { padding: var(--s4) 0; gap: var(--s3); }
}
@media (max-width: 560px) {
  .foot-grid { grid-template-columns: 1fr; }
  .foot-legal { align-items: flex-start; flex-direction: column; }
}

/* ---- entrance (replays every time the footer comes back into view; .is-in is set by js/footer-pile.js).
   Hidden states exist only with JS and only when motion is allowed, so no-JS and reduced motion show everything at rest. */
@media (prefers-reduced-motion: no-preference) {
  .js footer.foot .f-L { transform-origin: 0 100%; transition: transform var(--x-letter) var(--x-out) var(--d, 0ms), opacity .3s linear var(--d, 0ms); }
  .js footer.foot:not(.is-in) .f-L { opacity: 0; transform: translate3d(0, .55em, 0) rotate(30deg); transition: none; }

  .js footer.foot .foot-top::after, .js footer.foot .foot-legal::before { transition: transform var(--x-line) var(--x-io) var(--d, 0ms); }
  .js footer.foot:not(.is-in) .foot-top::after, .js footer.foot:not(.is-in) .foot-legal::before { transform: scaleX(0); transition: none; }

  .js footer.foot .foot-logo, .js footer.foot .foot-line, .js footer.foot .foot-fr, .js footer.foot .foot-brand .cap, .js footer.foot .foot-h, .js footer.foot .foot-legal p {
    transition: transform var(--x-row) var(--x-out) var(--d, 0ms), opacity .5s linear var(--d, 0ms); }
  .js footer.foot:not(.is-in) .foot-logo, .js footer.foot:not(.is-in) .foot-line, .js footer.foot:not(.is-in) .foot-fr, .js footer.foot:not(.is-in) .foot-brand .cap,
  .js footer.foot:not(.is-in) .foot-h, .js footer.foot:not(.is-in) .foot-legal p { opacity: 0; transform: translate3d(0, 60%, 0); transition: none; }

  /* link rows: the label rises out of a mask (the li clips it), 50 ms apart */
  .js footer.foot .foot-col li > a > *, .js footer.foot .foot-legal li > a > * { transition: transform var(--x-row) var(--x-out) var(--d, 0ms); }
  .js footer.foot:not(.is-in) .foot-col li > a > *, .js footer.foot:not(.is-in) .foot-legal li > a > * { transform: translate3d(0, 115%, 0); transition: none; }

  /* the quote button wipes up from the bottom */
  .js footer.foot .foot-top .a-btn { transition: clip-path var(--x-row) var(--x-io) var(--d, 0ms), background var(--ctl) var(--ease), color var(--ctl) var(--ease); }
  .js footer.foot:not(.is-in) .foot-top .a-btn { clip-path: inset(100% 0 0 0); transition: none; }
  .js footer.foot.is-in .foot-top .a-btn { clip-path: inset(0); }

  /* idle: the wordmark breathes, 1 to 1.04 over 6 s */
  @keyframes f-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.04); } }
  .foot-logo img { animation: f-breathe 6s ease-in-out infinite; }
}
@media (prefers-reduced-motion: reduce) {
  .f-ch > i, .ico svg { transition: none; }
}
