/* ==========================================================================
   SITE FOOTER — shared by the homepage and every project page.

   Built because the project pages needed a consistent ending and because
   CLAUDE.md §9's footer byline had never actually been placed anywhere. One
   component now does both jobs, so the two cannot drift.

   WHAT IT DOES NOT CONTAIN: contact links. On the homepage they already sit
   in the About field directly above this, and repeating them one block later
   would read as a stutter rather than as a second chance. On a project page
   they are one click away through the About link in the masthead. The footer
   is the end of the page, not a second navigation.

   The back-to-top conch lives here rather than inside About, so there is
   exactly one of it on the homepage and the same one on every other page. It
   is the same mark, same valampiri flip, same paper-on-whatever treatment —
   only the ground changes, which is the point.
   ========================================================================== */

.site-footer {
  padding-block: clamp(var(--sp-xl), 10vh, var(--sp-2xl));
  padding-inline: var(--gutter);
  text-align: center;
}

/* On the homepage the footer follows the inverted About field, so it takes
   that field's colours and reads as its last line rather than as a cream
   strip cutting the arrival in half. */
/* Read off the footer that is actually on the page, rather than set per page
   in the markup. A page that switches footer variant later takes the right
   overscroll tail with it and cannot be forgotten. Browsers without :has()
   keep the --paper default, which is the behaviour that shipped before. */
:root:has(.site-footer--inverted) { --overscroll-tail: var(--kumkumam); }

.site-footer--inverted {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  background: var(--kumkumam);
  color: var(--paper);
  /* The field above already carries the top of this block; without pulling
     up, the two would show a seam where their paddings meet. */
  margin-block-start: 0;
  padding-block-start: 0;
}


/* --- Back to top ---------------------------------------------------------
   A real link with a real accessible name, not a scripted click target: it
   takes keyboard focus in order and works with no JavaScript. The SVG stays
   aria-hidden, because the name belongs to the anchor — an anchor whose only
   content is decorative artwork announces as an unlabelled link. */

.site-footer__top {
  display: block;
  width: max-content;
  margin-inline: auto;
  /* The anchor carries the hit area, the SVG only the artwork. A bare 64px
     stroke is a thin thing to ask a thumb to find. */
  padding: var(--sp-xs);
  -webkit-tap-highlight-color: transparent;
}

.site-footer__conch {
  display: block;
  width: clamp(64px, min(9vh, 8vw), 104px);
  aspect-ratio: 666 / 908;
  height: auto;
  max-width: none;
  /* Paper on the inverted ground, kumkumam on paper. Set per context below
     rather than here, so the same markup serves both. */
  opacity: 0.62;
  transition: opacity var(--t-quick) var(--ease),
              transform var(--t-slow) var(--ease);
}

.site-footer--inverted .site-footer__conch { fill: var(--paper); }
.site-footer:not(.site-footer--inverted) .site-footer__conch { fill: var(--kumkumam); }

/* Coming up to full strength is the whole hover state. It must not go to
   --kumkumam-lit on the inverted ground: that is a near-neighbour of the
   field and would make the mark disappear rather than respond. */
.site-footer__top:hover .site-footer__conch,
.site-footer__top:focus-visible .site-footer__conch {
  opacity: 1;
  transform: translateY(-3px);
}

.site-footer--inverted .site-footer__top:focus-visible {
  outline: 2px solid var(--paper);
  outline-offset: 2px;
}

.site-footer:not(.site-footer--inverted) .site-footer__top:focus-visible {
  outline: 2px solid var(--kumkumam);
  outline-offset: 2px;
}


/* --- Byline --------------------------------------------------------------
   §9, verbatim. Quiet: it is a signature, not a statement. */

.site-footer__byline {
  margin: var(--sp-l) auto 0;
  max-width: none;
  font-size: var(--type-small);
  letter-spacing: 0.06em;
  line-height: var(--lh-snug);
}

.site-footer--inverted .site-footer__byline { color: var(--paper); opacity: 0.82; }
.site-footer:not(.site-footer--inverted) .site-footer__byline { color: var(--ink-muted); }


@media (prefers-reduced-motion: reduce) {
  .site-footer__conch { transition: none; }
  .site-footer__top:hover .site-footer__conch,
  .site-footer__top:focus-visible .site-footer__conch { transform: none; }
}


/* --- The draw ------------------------------------------------------------
   The same masked reveal as the hero: conch-stroke swept along the spine by
   stroke-dashoffset, uncovering the tapered outline underneath. The taper is
   the artwork, not something CSS reconstructs.

   RESOLVED BY DEFAULT — offset 0, fully drawn. js/footer-conch.js adds
   .is-armed to wind it back and .is-drawing to release it, so every failure
   path (no script, no IntersectionObserver, reduced motion) lands on a
   finished conch rather than an empty frame.

   Stroke properties are set on the <use>, not the referenced path: they are
   inherited properties, so they reach the cloned geometry inside. Width 32
   clears the outline's measured 21-unit waist with margin, exactly as in the
   hero — a narrower mask clips the artwork at its widest point. */

.site-footer__mask {
  fill: none;
  stroke: #fff;                 /* mask luminance: white reveals */
  stroke-width: 32;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1000 1000;  /* pathLength is normalised to 1000 */
  stroke-dashoffset: 0;
}

.site-footer.is-armed .site-footer__mask { stroke-dashoffset: 1000; }

/* Faster than the hero's draw, deliberately. --t-draw is ~2.7s, which is
   right for the opening moment of the site but too slow for a mark you meet
   at the bottom of a page you are already leaving. --t-slow is ~1.3s. */
.site-footer.is-drawing .site-footer__mask {
  animation: footer-conch-draw var(--t-slow) linear forwards;
}

@keyframes footer-conch-draw {
  from { stroke-dashoffset: 1000; }
  to   { stroke-dashoffset: 0; }
}

/* Belt and braces: the script already refuses to arm under the preference,
   but if the class arrived by any other route the sequence is neutralised
   here rather than merely sped up. */
@media (prefers-reduced-motion: reduce) {
  .site-footer.is-armed .site-footer__mask,
  .site-footer.is-drawing .site-footer__mask {
    animation: none;
    stroke-dashoffset: 0;
  }
}
