/* ============================================================
   Saltado Sessions: the one shared site footer.
   Every page links this file; footer styles live ONLY here.
   Relies on each page's design tokens (--sidebar, --border,
   --text, --muted, --accent) and the shared .wrap/.brand markup.
   ============================================================ */
.site-footer {
  position: relative;
  border-top: 1px solid var(--border);
  background: var(--sidebar);
  padding: 72px 0 40px;
  color: var(--muted);
  font-size: 13px;
}
/* Faint bar/beat ticks along the top edge, the hero ruler's echo. */
.site-footer::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 9px;
  /* --rule/--rule-soft (site.css) rather than literal white: on classic-light
     the footer sits on #b2b2b2 and a 13% white tick over it is invisible, so
     the ruler motif vanished in exactly one of the six themes. */
  background-image:
    repeating-linear-gradient(90deg, var(--rule, rgba(255, 255, 255, 0.13)) 0 1px, transparent 1px 176px),
    repeating-linear-gradient(90deg, var(--rule-soft, rgba(255, 255, 255, 0.045)) 0 1px, transparent 1px 44px);
  pointer-events: none;
}
.footer-top { display: grid; grid-template-columns: 2.1fr 1fr 1.35fr 1fr 0.9fr; gap: 44px; }
.footer-brand .brand { margin-bottom: 18px; }
.footer-brand p { font-size: 13px; max-width: 30ch; line-height: 1.75; }
.footer-brand .tag-lead { display: block; color: var(--text); }
/* The product-status line: the ONE early-access sentence, byte-identical on
   every page. It lives here rather than on the homepage alone because a
   visitor who lands on a guide page from search has no pricing card and no
   FAQ above them, and "the price rises, yours does not" is the kind of thing
   they should read before they buy, not after. Typographically it mirrors the
   pricing card's .price-early (accent lead, muted body) so the two read as
   one statement rather than two different claims. Selector is scoped through
   .footer-brand to outrank the .footer-brand p sizing above it. */
.footer-brand .footer-status {
  margin: 15px 0 0; max-width: 34ch;
  font-size: 12.5px; line-height: 1.65;
}
.footer-brand .footer-status strong { color: var(--accent-ink); font-weight: 600; }
.footer-brand .footer-status a {
  color: inherit; text-decoration: underline; text-underline-offset: 2px;
  transition: color 0.13s ease;
}
.footer-brand .footer-status a:hover { color: var(--accent-ink); }
.footer-col .fh {
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.17em;
  color: var(--muted); margin: 7px 0 16px;
}
/* opacity 0.75, not 0.6: the dim-to-bright ramp is the hover affordance and is
   worth keeping, but 0.6 put --text at 3.26:1 on classic-light, 4.33 on
   classic-dark and 4.46 on twenty-four-carat. 0.74 is the lowest value that
   clears 4.5:1 in all six themes; 0.75 is that rounded, and still reads
   clearly quieter than the full-strength column heads above it. */
.footer-col a {
  display: block; width: fit-content;
  color: var(--text); opacity: 0.75;
  text-decoration: none; font-size: 13.5px;
  padding: 5px 0;
  transition: opacity 0.13s ease, color 0.13s ease;
}
.footer-col a:hover { opacity: 1; color: var(--accent-ink); }
/* "Product updates" — a list Jules owns, in the brand column under the blurb.
   Not a newsletter (no promised cadence) and not a launch waitlist; the copy
   stays quiet on purpose. Posts to the ops hub via /footer.js. */
.footer-sub { margin-top: 24px; max-width: 32ch; }
.footer-sub .fh {
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.17em;
  color: var(--muted); margin: 0 0 8px;
}
/* No opacity multiplier. This text already inherits --muted from .site-footer,
   so 0.72 was muting an already-muted token twice and landed it at 2.81 to
   3.71:1 across the themes. Even at full strength --muted on --sidebar is only
   4.52 to 5.80:1, so there was no headroom to spend. Same reasoning removed the
   0.8 from the placeholder and the 0.6 from .footer-bottom .legal below. */
.footer-sub-note { font-size: 12.5px; line-height: 1.6; margin: 0 0 11px; }
.footer-sub-row { display: flex; gap: 8px; }
/* var(--radius), not 8px: site.css declares the scale as 2px with 3px for cards
   and menus, and these two controls were the only 8px corners on the site. */
.footer-sub input {
  flex: 1; min-width: 0;
  background: transparent; color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 9px 11px; font: inherit; font-size: 13px;
}
.footer-sub input::placeholder { color: var(--muted); }
/* The border tint alone is not a focus indicator: --accent measured 1.84:1
   against the footer on classic-light, and outline:none stripped the only
   thing that was. The ring is restored for keyboard focus (:focus-visible, so
   clicking the field still gets the quiet border-only treatment) and matches
   the global site.css pattern rather than inventing a second one. */
.footer-sub input:focus { outline: none; border-color: var(--accent-ink); }
.footer-sub input:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.footer-sub button {
  flex: none; width: 42px;
  background: transparent; color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  cursor: pointer; font-size: 16px; line-height: 1;
  transition: border-color 0.13s ease, color 0.13s ease;
}
.footer-sub button:hover { border-color: var(--accent-ink); color: var(--accent-ink); }
.footer-sub button:disabled { opacity: 0.5; cursor: default; }
.footer-sub-msg { font-size: 12px; line-height: 1.5; margin: 9px 0 0; }
.footer-sub-msg.ok { color: var(--accent-ink); }
/* var(--error-ink) rather than the literal #d98c8c, which was a dark-theme
   pink and measured 1.23:1 on classic-light, the single worst pair on the
   site. site.css gives --error-ink a default so it resolves on the 29 pages
   that never declare --error inline. */
.footer-sub-msg.err { color: var(--error-ink); }
.footer-bottom {
  margin-top: 68px; padding-top: 24px;
  /* var(--border), the divider token .site-footer itself uses, in place of a
     literal 7% white that classic-light rendered as nothing. */
  border-top: 1px solid var(--border);
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: 10px 48px;
  font-size: 11px; line-height: 1.75;
}
/* The legal line is 11px and already sits in --muted, which tops out at
   4.52:1 on --sidebar. The old opacity 0.6 drove it to 2.32 to 3.01:1 in
   every theme, the worst text pair in these two stylesheets, on the one
   block whose whole job is to be readable. It stays visually quiet by
   being small and muted, which is enough. */
.footer-bottom .legal {
  /* min(280px, 100%) rather than a bare 280px: a flex item's min-width is a
     hard floor, so on a viewport under 328px (the .wrap's 24px gutters take
     48) the legal block pushed past the content box and gave the whole page a
     horizontal scrollbar. The min() keeps the 280px preference everywhere it
     fits and lets it shrink on the narrowest devices. */
  order: -1; flex: 1; min-width: min(280px, 100%); max-width: 78ch;
}
@media (max-width: 860px) {
  .site-footer { padding: 56px 0 36px; }
  .footer-top { grid-template-columns: 1fr 1fr; gap: 34px 24px; }
  .footer-brand { grid-column: 1 / -1; }
  .footer-bottom { margin-top: 48px; }
  /* Touch sizing. At 13.5px on a 1.55 line box the desktop 5px padding gives a
     31px tall link, under every touch-target guideline going, and the footer is
     where a phone visitor goes to find a guide page. 10px takes it to ~41px
     without moving anything on a desktop, where the rule does not apply. The
     padding goes on the link (which is display:block) rather than on a wrapper,
     so the taller area IS the clickable one. */
  .footer-col a { padding: 10px 0; }
}
