/* ==========================================================================
   Vertical AI Systems: site footer (site/css/footer.css)
   --------------------------------------------------------------------------
   The footer is chrome. It lives once in site/index.html
   (<footer class="foot">); scripts/build-pages.mjs copies it into every
   generated page, and site/start/index.html keeps a hand copy. Link this
   file after home.css, components.css and site-menu.css. Behaviour lives in
   site/js/footer.js (the year, the Vancouver clock, the pin pulse while the
   map is on screen, back to top). Without it the footer is complete.

   Top to bottom:
     .foot__close   the closing band: one line, the booking button and the
                    price floor
     .foot__main    brand, contact and socials, then four link columns
     .foot__map     the dot-matrix map (assets/img/footer-map.svg, a mask
                    painted with a token), the pin on Vancouver, its caption
     .foot__word    the big lockup, decorative (aria-hidden)
     .foot__base    copyright, legal links, back to top

   Ground: the back cover of the manual, ink with bone type. Every colour is
   a theme token or a mix of two. The logo itself (.vs-logo, .vs-mark) is
   styled in home.css; this file only sizes the footer's instances.
   ========================================================================== */

/* The map block below is written by scripts/build-map.mjs. */
/* map:start (generated by scripts/build-map.mjs from its frame and labels; do not edit) */
.foot {
  --map-ratio: 1.5952;
  --map-pin-x: 0.5311;
  --map-pin-y: 0.4759;
  --map-border-x: 0.7869;
  --map-border-y: 0.5324;
  --map-ocean-x: 0.1557;
  --map-ocean-y: 0.5224;
}
/* map:end */

.foot {
  --foot-bg: var(--sc-ink);
  --foot-ink: var(--sc-canvas);
  --foot-soft: color-mix(in oklab, var(--sc-canvas) 72%, var(--sc-ink));
  --foot-line: color-mix(in oklab, var(--sc-canvas) 13%, transparent);
  --foot-line-strong: color-mix(in oklab, var(--sc-canvas) 30%, transparent);
  --foot-panel: color-mix(in oklab, var(--sc-canvas) 4%, var(--sc-ink));
  /* The ring green, lifted for a dark ground (the reverse mark does the same). */
  --foot-ok: color-mix(in oklab, var(--vs-ok) 62%, var(--sc-canvas));
  --foot-ease: var(--vs-ease-card, cubic-bezier(.2, .8, .2, 1));
  /* The map mask's rendered width, and its height from the SVG's ratio. */
  --map-w: clamp(1100px, 118vw, 1760px);
  --map-h: calc(var(--map-w) / var(--map-ratio));

  position: relative;
  background: var(--foot-bg);
  color: var(--foot-ink);
  padding-top: clamp(3.5rem, 8vw, 6.5rem);
  /* The planes behind the open menu scale this element; keep it one box. */
  isolation: isolate;
}
.foot :focus-visible { outline-color: var(--foot-ink); }
.foot .vs-btn--primary:focus-visible { outline-color: var(--foot-ink); }

.foot__wrap {
  max-width: var(--sc-maxw);
  margin-inline: auto;
  padding-inline: var(--sc-gutter);
}

.foot__h,
.foot__kicker,
.foot__note {
  margin: 0;
  font-family: var(--vs-font-mono, ui-monospace, monospace);
  font-size: var(--sc-t-xs);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--foot-soft);
}

/* ------------------------------------------------------- closing band -- */
.foot__close {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--sc-5) var(--sc-7);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  border-bottom: 1px solid var(--foot-line);
}
.foot__kicker {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: var(--sc-4);
}
.foot__kicker::before {
  content: "";
  flex: none;
  width: 0.875rem;
  height: 3px;
  background: var(--sc-accent);
}
.foot__close-title {
  margin: 0;
  max-width: 17ch;
  font-family: var(--sc-font-display);
  font-weight: var(--vs-display-weight, 600);
  font-size: clamp(2.2rem, 1.3rem + 3.4vw, 4.4rem);
  line-height: 0.98;
  letter-spacing: var(--vs-display-track, -0.03em);
  text-wrap: balance;
}
.foot__close-side {
  display: grid;
  justify-items: end;
  gap: 0.8rem;
}
.foot__cta { min-height: 3.25rem; padding-inline: 1.5rem; font-size: var(--sc-t-base); }
.foot__note { letter-spacing: 0.04em; text-transform: none; }

/* ---------------------------------------------------------------- main -- */
.foot__main {
  display: grid;
  grid-template-columns: minmax(15rem, 1fr) minmax(0, 3.3fr);
  gap: var(--sc-7) clamp(2rem, 5vw, 5rem);
  padding-block: clamp(2.75rem, 5vw, 4.5rem);
}

.foot__id {
  display: grid;
  align-content: start;
  justify-items: start;
  gap: var(--sc-5);
}
/* 1.75rem, not the 2rem it was until 17 Sep 2026: the name gained a word,
   and at 2rem the one-line lockup ran up against the Services column. */
.foot__logo { --logo-mark: 1.75rem; color: var(--foot-ink); }
.foot__about {
  margin: 0;
  max-width: 30ch;
  font-size: var(--sc-t-sm);
  line-height: 1.5;
  color: var(--foot-soft);
  text-wrap: pretty;
}
.foot__contact { display: grid; gap: var(--sc-3); }
.foot__mail {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 2.75rem;
  color: var(--foot-ink);
  font-size: var(--sc-t-sm);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: var(--foot-line-strong);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.35em;
  transition: text-decoration-color 160ms var(--foot-ease);
}
.foot__mail svg { flex: none; width: 1.125rem; height: 1.125rem; color: var(--foot-soft); }
.foot__mail:hover { text-decoration-color: currentColor; }

.foot__social {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.foot__social a {
  position: relative;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  color: var(--foot-ink);
  border: 1px solid var(--foot-line-strong);
  border-radius: 999px;
  transition:
    background-color 160ms var(--foot-ease),
    border-color 160ms var(--foot-ease),
    color 160ms var(--foot-ease),
    transform 240ms var(--foot-ease);
}
.foot__social a:focus-visible { outline-offset: 3px; border-radius: 999px; }
.foot__social svg { width: 1.125rem; height: 1.125rem; }
/* A name tag above the icon on hover and keyboard focus. The link's own
   aria-label names it for screen readers, so the tag is hidden from them. */
.foot__tip {
  position: absolute;
  bottom: calc(100% + 0.5rem);
  left: 50%;
  padding: 0.3rem 0.5rem;
  font-family: var(--vs-font-mono, ui-monospace, monospace);
  font-size: 0.6875rem;
  line-height: 1;
  letter-spacing: 0.04em;
  white-space: nowrap;
  color: var(--foot-bg);
  background: var(--foot-ink);
  border-radius: 4px;
  pointer-events: none;
  opacity: 0;
  translate: -50% 4px;
  transition: opacity 160ms var(--foot-ease), translate 160ms var(--foot-ease);
}
.foot__social a:focus-visible .foot__tip { opacity: 1; translate: -50% 0; }
@media (hover: hover) {
  .foot__social a:hover {
    color: var(--foot-bg);
    background: var(--foot-ink);
    border-color: var(--foot-ink);
    transform: translateY(-2px);
  }
  .foot__social a:hover .foot__tip { opacity: 1; translate: -50% 0; }
}

/* Link columns. */
.foot__nav {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sc-6) var(--sc-5);
}
.foot__h { margin-bottom: var(--sc-3); }
.foot__h a {
  color: inherit;
  text-decoration: none;
  transition: color 160ms var(--foot-ease);
}
.foot__h a:hover { color: var(--foot-ink); }
.foot__list {
  margin: 0;
  padding: 0;
  list-style: none;
}
.foot__list li {
  padding-block: 0.42rem;
  font-size: var(--sc-t-sm);
  line-height: 1.35;
  text-wrap: pretty;
}
/* Inline, so a wrapped name keeps its tag and arrow right after the text. */
.foot__link {
  color: var(--foot-ink);
  text-decoration: none;
  /* The underline draws in from the left on hover. */
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat;
  padding-bottom: 2px;
  transition: background-size 260ms var(--foot-ease), color 160ms var(--foot-ease);
}
.foot__link:hover,
.foot__link:focus-visible,
.foot__link[aria-current="page"] { background-size: 100% 1px; }
/* The page you are on: the approval point. */
.foot__link[aria-current="page"]::before {
  content: "";
  display: inline-block;
  width: 0.4rem;
  height: 0.4rem;
  margin: 0 0.6rem 0 0.2rem;
  vertical-align: 0.12em;
  border-radius: 50%;
  background: var(--sc-accent);
  box-shadow: 0 0 0 2px var(--foot-bg), 0 0 0 3.5px var(--foot-ok);
}
.foot__ext {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  margin-left: 0.35em;
  vertical-align: 0;
  color: var(--foot-soft);
}
.foot__tag {
  display: inline-block;
  margin-left: 0.5em;
  vertical-align: 0.1em;
  padding: 0.18rem 0.4rem;
  font-family: var(--vs-font-mono, ui-monospace, monospace);
  font-size: 0.6875rem;
  line-height: 1;
  letter-spacing: 0.04em;
  color: var(--foot-soft);
  border: 1px solid var(--foot-line-strong);
  border-radius: 999px;
}

/* ----------------------------------------------------------------- map -- */
.foot__map {
  position: relative;
  margin: 0;
  overflow: hidden;
  background: var(--foot-panel);
  border: 1px solid var(--foot-line);
  border-radius: var(--vs-card-r, 10px);
}
/* The drawing: the mask, the labels and the pin. The caption lies over it
   on wide screens and sits under it on phones. */
.foot__map-canvas {
  position: relative;
  height: clamp(17rem, 29vw, 26rem);
}
.foot__map-art {
  position: absolute;
  inset: 0;
  background-color: var(--foot-ink);
  opacity: 0.6;
  -webkit-mask: url("/assets/img/footer-map.svg") calc(var(--map-pin-x) * 100%) calc(var(--map-pin-y) * 100%) / var(--map-w) auto no-repeat;
  mask: url("/assets/img/footer-map.svg") calc(var(--map-pin-x) * 100%) calc(var(--map-pin-y) * 100%) / var(--map-w) auto no-repeat;
}
/* The map's corners, as on the menu's preview plate. */
.foot__map-canvas::before,
.foot__map-canvas::after {
  content: "";
  position: absolute;
  z-index: 1;
  width: 14px;
  height: 14px;
  border: solid var(--foot-line-strong);
  pointer-events: none;
}
.foot__map-canvas::before { top: 10px; left: 10px; border-width: 1px 0 0 1px; }
.foot__map-canvas::after { right: 10px; bottom: 10px; border-width: 0 1px 1px 0; }

/* A label anchored to a map point (--lx, --ly, fractions of the SVG). The
   mask puts the pin's fraction of the SVG on the same fraction of the box,
   so any other point sits at that spot plus its offset at the mask's size. */
.foot__map-label {
  position: absolute;
  z-index: 1;
  left: calc(var(--map-pin-x) * 100% + (var(--lx) - var(--map-pin-x)) * var(--map-w));
  top: calc(var(--map-pin-y) * 100% + (var(--ly) - var(--map-pin-y)) * var(--map-h));
  font-family: var(--vs-font-mono, ui-monospace, monospace);
  font-size: 0.6875rem;
  line-height: 1;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--foot-soft);
  pointer-events: none;
}
/* Either side of the border line, at the right edge. */
.foot__map-label--canada,
.foot__map-label--usa {
  --lx: var(--map-border-x);
  --ly: var(--map-border-y);
  left: auto;
  right: 1.5rem;
}
.foot__map-label--canada { translate: 0 calc(-100% - 0.6rem); }
.foot__map-label--usa { translate: 0 0.6rem; }
.foot__map-label--ocean {
  --lx: var(--map-ocean-x);
  --ly: var(--map-ocean-y);
  left: max(1.5rem, calc(var(--map-pin-x) * 100% + (var(--lx) - var(--map-pin-x)) * var(--map-w)));
  translate: 0 -50%;
  font-style: italic;
  letter-spacing: 0.22em;
}

/* The pin: the logo's approval point. A ring in the lifted green, an ink
   gap, the orange dot, and a halo of ground that clears the dots. */
.foot__pin {
  position: absolute;
  z-index: 2;
  left: calc(var(--map-pin-x) * 100%);
  top: calc(var(--map-pin-y) * 100%);
  width: 1.75rem;
  height: 1.75rem;
  translate: -50% -50%;
  border: 3px solid var(--foot-ok);
  border-radius: 50%;
  background: var(--foot-panel);
  box-shadow: 0 0 0 5px color-mix(in oklab, var(--foot-panel) 75%, transparent);
}
.foot__pin::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--sc-accent);
}
/* The pulse: a thin ring that widens and fades. It runs five times each
   time the map comes on screen (footer.js sets .is-live), and keeps going
   while the pointer rests on the map. */
.foot__pin::before {
  content: "";
  position: absolute;
  inset: -3px;
  border: 1.5px solid var(--foot-ok);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}
.foot__map.is-live .foot__pin::before {
  animation: foot-pulse 2.8s var(--sc-ease-out, ease-out) 0.4s 5 both;
}
@media (hover: hover) {
  .foot__map.is-live:hover .foot__pin::before { animation-iteration-count: infinite; }
}
@keyframes foot-pulse {
  0% { opacity: 0.85; transform: scale(1); }
  60% { opacity: 0; transform: scale(2.8); }
  100% { opacity: 0; transform: scale(2.8); }
}

.foot__place {
  position: absolute;
  z-index: 3;
  left: var(--sc-4);
  bottom: var(--sc-4);
  display: grid;
  gap: 0.35rem;
  max-width: calc(100% - 2 * var(--sc-4));
  padding: 0.9rem 1.1rem 1rem;
  background: color-mix(in oklab, var(--foot-bg) 90%, transparent);
  border: 1px solid var(--foot-line);
  border-radius: 8px;
}
.foot__place-name {
  margin: 0;
  font-family: var(--sc-font-display);
  font-weight: var(--vs-display-weight, 600);
  font-size: var(--sc-t-base);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--foot-ink);
}
.foot__place-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  margin: 0;
  font-family: var(--vs-font-mono, ui-monospace, monospace);
  font-size: var(--sc-t-xs);
  line-height: 1.35;
  letter-spacing: 0.02em;
  color: var(--foot-soft);
  font-variant-numeric: tabular-nums;
}
.foot__clock { color: var(--foot-ink); }

/* ------------------------------------------------------------ wordmark -- */
.foot__word {
  container-type: inline-size;
  margin: clamp(2.5rem, 6vw, 5rem) 0 0;
  color: var(--foot-ink);
  user-select: none;
  /* A net for an unexpected fallback face: never a sideways scroll. */
  overflow-x: clip;
}
/* Sized to the footer's width. Re-measured in Archivo at width 125 on
   17 Sep 2026, when the name became VERTICAL AI SYSTEMS: the text is
   14.33em wide, the mark 1.03em and the gap 0.16em, 15.52em in all, so
   6.4cqi fills the line with a hair to spare (space-between takes it up).
   Any fallback face is narrower. */
.foot__word-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.16em;
  font-size: min(5.7vw, 5rem);
  font-size: 6.4cqi;
  line-height: 1;
}
.foot__word .vs-mark { height: 0.86em; width: calc(0.86em * 104 / 87); }
.foot__word-text {
  font-family: "Archivo", var(--sc-font-display);
  font-stretch: 125%;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 0.8;
  text-transform: uppercase;
  white-space: nowrap;
  /* Optical: caps sit on the line with no descender space below. */
  padding-top: 0.04em;
}
/* Phones: the name on two lines beside a mark two lines tall. The widest
   line is now AI SYSTEMS at 7.68em (it was VERTICAL at 6.35em); with the
   mark and the gap the lockup is 9.94em, so 10cqi fills the width. */
@media (max-width: 560px) {
  .foot__word-inner { justify-content: flex-start; gap: 0.2em; font-size: 10cqi; }
  .foot__word .vs-mark { height: 1.72em; width: calc(1.72em * 104 / 87); }
  .foot__word-text > span { display: block; }
  .foot__word-text { line-height: 0.86; }
}

/* ---------------------------------------------------------------- base -- */
.foot__base {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.75rem;
  margin-top: clamp(1.75rem, 3.5vw, 3rem);
  padding-block: 1.25rem calc(1.5rem + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--foot-line);
  font-size: var(--sc-t-xs);
  color: var(--foot-soft);
}
.foot__legal { margin: 0 auto 0 0; }
.foot__base ul {
  display: flex;
  gap: 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.foot__base a {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 2.75rem;
  color: var(--foot-ink);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.35em;
  transition: text-decoration-color 160ms var(--foot-ease);
}
.foot__base a:hover { text-decoration-color: currentColor; }
.foot__top svg {
  width: 0.875rem;
  height: 0.875rem;
  transition: transform 240ms var(--foot-ease);
}
.foot__top:hover svg { transform: translateY(-2px); }

/* ---------------------------------------------------------- responsive -- */
@media (max-width: 1180px) {
  .foot__main { grid-template-columns: minmax(0, 1fr); }
  .foot__id {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: var(--sc-7);
  }
  .foot__about { grid-column: 1; }
  .foot__contact { grid-column: 2; grid-row: 1 / span 2; justify-self: end; justify-items: end; }
}
@media (max-width: 900px) {
  .foot__nav { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .foot__close { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .foot__close-side { justify-items: start; }
  .foot__id { grid-template-columns: minmax(0, 1fr); }
  .foot__contact { grid-column: auto; grid-row: auto; justify-self: start; justify-items: start; }
}
@media (max-width: 560px) {
  /* The footer logo is one line and never stacks, so the longer name (17 Sep
     2026) is sized down here to clear the gutter at 320px. */
  .foot__logo { --logo-mark: 1.625rem; }
  .foot__nav { grid-template-columns: minmax(0, 1fr); gap: var(--sc-5); }
  .foot__cta { width: 100%; }
  .foot__close-side { justify-items: stretch; }
  .foot__map-canvas { height: 17rem; }
  .foot__map-label--ocean { display: none; }
  .foot__place {
    position: static;
    max-width: none;
    padding: 0.9rem 1rem 1rem;
    background: none;
    border: 0;
    border-top: 1px solid var(--foot-line);
    border-radius: 0;
  }
  .foot__legal { flex-basis: 100%; }
}

/* -------------------------------------------------------------- motion -- */
@media (prefers-reduced-motion: reduce) {
  .foot__mail,
  .foot__social a,
  .foot__tip,
  .foot__h a,
  .foot__link,
  .foot__base a,
  .foot__top svg { transition: none; }
  .foot__social a:hover,
  .foot__top:hover svg { transform: none; }
  .foot__map.is-live .foot__pin::before { animation: none; }
}

/* ------------------------------------------------------ forced colours -- */
@media (forced-colors: active) {
  .foot { border-top: 1px solid CanvasText; }
  .foot__map { border-color: CanvasText; }
  .foot__map-art { forced-color-adjust: none; background-color: CanvasText; opacity: 0.5; }
  .foot__pin { forced-color-adjust: none; background: Canvas; border-color: CanvasText; box-shadow: none; }
  .foot__pin::after { forced-color-adjust: none; background: Highlight; }
  .foot__pin::before { display: none; }
  .foot__kicker::before { background: CanvasText; }
  .foot__link { background-image: none; }
  .foot__link:hover,
  .foot__link[aria-current="page"] { text-decoration: underline; }
  .foot__link[aria-current="page"]::before { forced-color-adjust: none; background: Highlight; box-shadow: none; }
  .foot__place { background: Canvas; border-color: CanvasText; }
  .foot__social a { border-color: CanvasText; }
}

/* --------------------------------------------------------------- print -- */
@media print {
  .foot { background: none; color: inherit; padding-top: 1rem; }
  .foot__close, .foot__map, .foot__word, .foot__social, .foot__top { display: none; }
}
