/* ---------- The site footer (2026-11-14 redesign: the footer redesign plan of 2026-11-14) ----------
   One footer for every page (owner, 2026-11-06: "the footer is not applied across all pages"). On the home, Testimonials and
   Media it is the foot of the closing section (footer.closing__foot inside section.closing) and stands on the skyline's dark
   ground under the horizon (js/closing-skyline.js puts the horizon on the foot's top edge). Every other page gets the same
   markup from partials/footer.html with .closing__foot--page, which gives it a graphite ground of its own. The content lives
   in partials/footer-body.html. The class names keep the closing__ prefix for the two wrappers, so the skyline still finds
   the foot; everything inside is foot__.

   Concept: the footer is the ground under the horizon. On the closing's centre line the tagline answers the heading, the six
   cities sit under it; then West Kite's tile row (Ask AI left, the channels right); a quiet meta row closes the content, and the word "preambient" stands on the page's bottom
   edge the way the buildings stand on the horizon. It is dark on dark; a warm light follows the pointer inside the letters
   (js/footer-wordmark.js), the one moving thing here.

   Spacing scale (8px): 8, 16, 24, 40, 56, 64, 80. Colour: white at stepped alphas on the ground, which is #0e0d16 to #07070b
   on the closing and #16171b on the pages; every text alpha used here is 9:1 or more on both. */
.closing__foot {
  --foot-serif: "Newsreader Text", "Newsreader Text fallback", Georgia, "Times New Roman", serif;
  --foot-sans: "Archivo", "Archivo fallback", system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --foot-mark: "Newsreader", "Newsreader Text", Georgia, serif;
  --foot-spectrum: linear-gradient(90deg, #8a9cc8, #78bed6 17%, #e4c698 34%, #929ec2 50%, #e4c698 66%, #78bed6 83%, #8a9cc8);
  --foot-flow: 12s;
  --foot-ease: cubic-bezier(.23, 1, .32, 1);
  position: relative; z-index: 2; color: rgba(255, 255, 255, .78); font-family: var(--foot-sans); font-size: 14px; line-height: 21px;
  text-align: left; }
.closing__foot--page { background: #16171b; }
/* On a page shorter than the window, the space under the footer continues its graphite (the root takes it). */
html:has(.closing__foot--page) { background: #16171b; }
.closing__foot--page { box-shadow: 0 1px 0 #16171b; overflow-x: clip; }
/* On the home, Testimonials and Media the page ends on the closing's dark ground, but the root's colour is the body's light
   stage, so a phone's overscroll past the end (iOS rubber band) showed a white band under the footer (Phil, 2026-11-14: "right
   now the bottom is white if i scroll all the way down"). While the closing's foot is on screen, js/footer-wordmark.js sets
   .is-foot on the root and the root takes the ground's last colour; at the top of the page it stays light, so the top bounce
   still matches the light hero. */
html.is-foot { background: #07070b; }
.closing__foot :focus-visible { outline-color: #b9a3e8; outline-offset: 3px; }
.foot-icons { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Plan v2: one axis. The closing's call is centred, so the footer's upper part continues its centre line: the tagline answers
   the heading (30px against 76px, the same face), the six cities sit under it as a dateline, then the Ask-AI row. Across the
   horizon the rhythm holds: Contact's foot is about 64px above it, the tagline's cap height about 72px below it. */
.foot__inner { padding-top: 56px; }
.foot__lead { grid-area: lead; display: grid; justify-items: center; text-align: center; }
.foot__tagline { margin: 0; font-family: var(--foot-serif); font-weight: 300; font-size: 30px; line-height: 1.2; letter-spacing: -0.012em;
  color: rgba(255, 255, 255, .92); text-wrap: balance; }
/* The six cities: a dateline, as a bank sets its offices. The dot trails each name, so a wrapped line never starts with one. */
.foot__cities { display: flex; flex-wrap: wrap; justify-content: center; margin: 12px 0 0; padding: 0; list-style: none; font-family: var(--foot-serif);
  font-weight: 300; font-size: 15px; line-height: 1.6; letter-spacing: .01em; color: rgba(255, 255, 255, .6); }
.foot__cities li { white-space: nowrap; }
.foot__cities li:not(:last-child)::after { content: "·"; margin: 0 10px; color: rgba(255, 255, 255, .28); }

/* Ask AI, as West Kite builds it (Phil, round 3: "designed like westkite"): a small label, then square outline tiles, 40px,
   radius 4px, 18px marks, 8px apart. The social marks use the same tile in the meta row, as on West Kite. */
/* The band, round 4 (Phil: the closing and the footer must fit "one screen well"): one row, three places. The tagline and
   cities hold the closing's centre line; Ask AI sits on the left edge and the channels on the right edge, as on West Kite's
   tile row; all three share one foot line. From 900px to 1199px the band stays one row (36px tiles, a 26px tagline, the
   cities three and three); below 900px the tagline goes above and the two tile groups share the row under it; on a phone
   everything stacks on the centre line. The DOM order is the reading
   order (tagline, Ask AI, channels); the grid places them. */
.foot__row { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); grid-template-areas: "ai lead follow"; align-items: end; column-gap: 40px; }
.foot__ai { grid-area: ai; display: grid; justify-items: start; }
.foot__follow { grid-area: follow; display: grid; justify-items: end; }
/* From 900px up the band is two shared rows (subgrid): the labels and the tagline share the first, on one baseline; the tiles
   and the cities share the second, on one centre line, so the three columns line up at every width. */
@media (min-width: 900px) {
  .foot__row { grid-template-rows: auto auto; row-gap: 12px; }
  .foot__row > .foot__lead, .foot__row > .foot__ai, .foot__row > .foot__follow { grid-row: 1 / span 2; grid-template-rows: subgrid; row-gap: 12px; }
  .foot__row .foot__label, .foot__row .foot__tagline { align-self: last baseline; margin: 0; }
  .foot__row .foot__tiles, .foot__row .foot__cities { align-self: center; margin: 0; }
}
@media (max-width: 899px) {
  .foot__inner { padding-top: 64px; }
  .foot__row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-areas: "lead lead" "ai follow"; row-gap: 56px; }
}
.foot__label { margin: 0 0 12px; font-family: var(--foot-sans); font-weight: 500; font-size: 13px; line-height: 18px; letter-spacing: 0;
  text-transform: none; color: rgba(255, 255, 255, .62); }
.foot__tiles { display: flex; gap: 8px; }
.foot__tile { position: relative; display: grid; place-items: center; width: 40px; height: 40px; border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 4px; color: rgba(255, 255, 255, .88); cursor: pointer; }
/* Without JavaScript the envelope has no address to open, so it does not show. */
.foot__tile[data-mail-icon]:not([href]) { display: none; }
.foot__tile svg { width: 18px; height: 18px; fill: currentColor; }
.foot__tile:active { transform: scale(.96); }
/* Optical sizes: the marks come from two families, so each is sized to the same visual weight (measured on screen at 2x):
   the solid LinkedIn, YouTube and Gemini marks read large, the thin Grok mark and the envelope read small. */
.foot__tile[data-tip="LinkedIn"] svg, .foot__tile[data-tip="YouTube"] svg { width: 16px; height: 16px; }
.foot__tile[data-tip="Gemini"] svg { width: 15px; height: 15px; }
.foot__tile[data-tip="Grok"] svg { width: 19px; height: 19px; }
.foot__tile[data-mail-icon] svg { width: 20px; height: 20px; }
.foot__tile { transition: background-color .16s ease, border-color .16s ease, color .16s ease, transform .16s var(--foot-ease); }
.foot__tile:focus-visible { outline: 2px solid #b9a3e8; outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  .foot__tile:hover { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .4); color: #fff; }
}
/* The name of each mark under it on hover and focus (the marks alone are not universally known). */
.foot__tile::after { content: attr(data-tip); position: absolute; top: calc(100% + 8px); left: 50%; transform: translate(-50%, -3px); z-index: 1;
  padding: 3px 8px; border: 1px solid rgba(255, 255, 255, .15); border-radius: 4px; background: #1c1c22; color: rgba(255, 255, 255, .92); font-family: var(--foot-sans); font-size: 12px;
  line-height: 16px; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .14s ease, transform .14s var(--foot-ease); }
.foot__tile:focus-visible::after { opacity: 1; transform: translate(-50%, 0); }
@media (hover: hover) and (pointer: fine) { .foot__tile:hover::after { opacity: 1; transform: translate(-50%, 0); } }
/* The tips open below the tiles, clear of the labels above and the hairline 48px below. The last channel's tip (the email
   address, about 160px wide) aligns to the tile's right edge, so it never reaches past the page and scrolls it sideways. */
.foot__follow .foot__tile:last-child::after { left: auto; right: 0; transform: translateY(-3px); }
.foot__follow .foot__tile:last-child:focus-visible::after { transform: none; }
@media (hover: hover) and (pointer: fine) { .foot__follow .foot__tile:last-child:hover::after { transform: none; } }

/* The meta row, under the one hairline: Careers under the Ask-AI group's left edge, the copyright on the right, so Careers
   never shares a place with the social channels (Phil, round 3: Careers not "in the same place as our social accounts"). */
.foot__meta { display: flex; justify-content: space-between; align-items: baseline; gap: 12px 40px; margin-top: 48px; padding: 20px 0 24px;
  border-top: 1px solid rgba(255, 255, 255, .12); }
.foot__copy { margin: 0; font-size: 13px; color: rgba(255, 255, 255, .58); }
/* Privacy rides on the copyright line, in its size and grey: a legal notice, not a page link (Phil, 2026-11-14: "ok"). */
.foot__privacy { color: inherit; text-underline-offset: 3px; transition: color .16s ease; }
@media (hover: hover) and (pointer: fine) { .foot__privacy:hover { color: #fff; text-decoration: underline; text-decoration-color: rgba(255, 255, 255, .5); } }
.foot__careers { font-size: 14px; color: rgba(255, 255, 255, .7); text-underline-offset: 4px; transition: color .16s ease; }
@media (hover: hover) and (pointer: fine) {
  .foot__careers:hover { color: #fff; text-decoration: underline; text-decoration-color: rgba(255, 255, 255, .5); }
}

/* The wordmark: the word spans the content width (js/footer-wordmark.js fits it to the box and sets --mark-size, --mark-top
   and --mark-h, so the ink of "p" meets the left edge, the "t" meets the right edge and the baseline sits on the page's foot).
   The values below are the no-JS fallback, close to the fitted ones at common widths. The light is a second copy under a
   radial mask that the script moves; it only exists for a fine pointer that hovers, and never under reduced motion. */
.foot__mark { position: relative; margin-top: 24px; user-select: none; }
.foot__mark-box { position: relative; height: var(--mark-h, 15.2vw); overflow: hidden; }
.foot__mark-word, .foot__mark-light { position: absolute; left: var(--mark-left, 0); top: var(--mark-top, -2.9vw); font-family: var(--foot-mark);
  font-weight: 400; font-size: var(--mark-size, 21.6vw); line-height: 1; letter-spacing: -0.02em; white-space: nowrap; }
.foot__mark-word { color: rgba(255, 255, 255, .09); }
.foot__mark-light { color: rgba(255, 247, 232, .22); opacity: 0; transition: opacity .6s ease;
  -webkit-mask-image: radial-gradient(circle 300px at var(--lx, 50%) var(--ly, 50%), #000, transparent 100%);
  mask-image: radial-gradient(circle 300px at var(--lx, 50%) var(--ly, 50%), #000, transparent 100%); }
.foot__mark.is-lit .foot__mark-light { opacity: 1; transition-duration: .4s; }
@media (prefers-reduced-motion: reduce), (hover: none) { .foot__mark-light { display: none; } }
@media (forced-colors: active) { .foot__mark { display: none; } }

/* 900px to 1199px: the band stays one row (see the band, above). After the tile rules, so the smaller tiles win. */
@media (min-width: 900px) and (max-width: 1199px) {
  .foot__row { column-gap: 24px; }
  .foot__lead { max-width: 360px; } /* caps the centre column: the grid would size it to the cities on one line */
  .foot__tagline { font-size: 26px; }
  .foot__tile { width: 36px; height: 36px; }
  .foot__tiles { gap: 6px; }
  .foot__cities li:nth-child(3)::after { content: none; }
  .foot__cities li:nth-child(n+4) { order: 2; }
  .foot__cities::before { content: ""; flex-basis: 100%; height: 0; order: 1; }
}

/* Phones: the centred stack; the cities wrap three and three; the two tile groups stack, each centred under its label; the
   meta row keeps Careers left and the copyright right; the wordmark keeps the content edges, as on desktop. */
@media (max-width: 809px) {
  .foot__inner { padding-top: 56px; }
  .foot__tagline { font-size: 24px; }
  /* The cities break three and three: the first three, an invisible full-width break, the last three. */
  .foot__cities li:nth-child(3)::after { content: none; }
  .foot__cities li:nth-child(n+4) { order: 2; }
  .foot__cities::before { content: ""; flex-basis: 100%; height: 0; order: 1; }
  .foot__row { grid-template-columns: minmax(0, 1fr); grid-template-areas: "lead" "ai" "follow"; row-gap: 48px; }
  .foot__ai, .foot__follow { justify-items: center; }
  .foot__meta { margin-top: 40px; }
}
@media (pointer: coarse) { .foot__tile { width: 44px; height: 44px; } }
@media (max-width: 360px) { .foot__tile { width: 40px; height: 40px; } .foot__tiles { gap: 6px; } }

/* The scroll stop (round 4: "a scroll stopper ... between ... this Preambient logo ... and this like line breaker"). On a
   desktop screen the closing call and the footer down to the meta row are one screen under the header, and the page rests
   there: the closing is a snap point (proximity, so scrolling never feels held); js/footer-wordmark.js settles a scroll that
   ends between that point and the page's end (the wordmark) on the nearer of the two. The closing's scroll-margin cancels the site's 16px scroll padding, so it rests flush under the
   header. Pages without the closing, phones and short screens scroll freely. */
@media (min-width: 900px) and (min-height: 640px) {
  html:has(.closing .closing__foot) { scroll-snap-type: y proximity; }
  /* The skyline canvas covers screen one only (the call and the footer down to its meta row); the wordmark's screen stands on
     the ground colour, the canvas's own last colour, so the join is seamless and the canvas keeps its sharpness and cost
     (review, 2026-11-14: it had grown to about 1,400px tall at 1440x900). */
  .closing:has(.closing__foot) { background: #07070b; }
  .closing:has(.closing__foot) > .closing__media { bottom: auto; height: calc(100svh - var(--nav-h, 64px)); }
  .closing:has(.closing__foot) { scroll-snap-align: start; scroll-margin-top: -16px; }
  /* The second resting place is a whole screen too: from the horizon down, the footer fills the screen under the header and
     the wordmark stands at its foot, so no part of the closing's heading shows above it. */
  .closing .foot__mark { display: flex; flex-direction: column; justify-content: flex-end; min-height: calc(100svh - var(--nav-h, 64px) - var(--closing-foot, 258px)); margin-top: 0; }
  /* A faint warm glow rises from the page's foot behind the word, the horizon's colour at 8%, so the dark above it reads as
     a pause before the word, not a gap. */
  .closing .foot__mark::before { content: ""; position: absolute; left: 50%; bottom: -160px; width: min(1100px, 90vw); height: 420px; transform: translateX(-50%);
    background: radial-gradient(closest-side, rgba(255, 247, 232, .08), transparent); pointer-events: none; }
}

/* Forced colours (Windows High Contrast): the decorative wordmark and its screen go, after the desktop rule above so its
   higher specificity cannot keep them. */
@media (forced-colors: active) { .foot__mark, .closing .foot__mark { display: none; } }

/* The spectrum edge. Owner, 2026-11-06: "add the rainbow bar border thing that is on the header to the footer too". The
   header's 2px moving spectrum line along the footer's top edge, full width, with its blurred copy spread either side of it.
   Pseudo-elements, so the markup does not change. Still under reduced motion; a plain line in forced colours. */
@keyframes foot-flow { from { background-position: 200% 0; } to { background-position: 0 0; } }
.closing__foot::before, .closing__foot::after { content: ""; position: absolute; left: 0; right: 0; pointer-events: none;
  background: var(--foot-spectrum) 0 0 / 200% 100% repeat-x; animation: foot-flow var(--foot-flow) linear infinite; }
.closing__foot::before { top: -1px; height: 2px; }
.closing__foot::after { top: -3px; height: 6px; filter: blur(5px); opacity: .7; }
@media (prefers-reduced-motion: reduce) { .closing__foot::before, .closing__foot::after { animation: none; } }
@media (forced-colors: active) { .closing__foot::before { background: CanvasText; height: 1px; } .closing__foot::after { display: none; } }
