/* ═══ SFTi — THE PUBLIC FOOTER + THE DISCLAIMER/POLICY ADD-IN. One card, both pages. ═══

   ── THE FOOTER IS COMPACT (operator: "why the disclaimers in the footer so spread out? look
      at Sfti pennies footer … its got the @Year statikfintech then our license and shit …
      match that but our theme with our links") ──
   Three lines, in this order and no others: the gold © line (year · company, and nothing else),
   one wrapped row of our links, and the cache-refresh control. What used to sit here — two prose
   paragraphs, two full-width justified link rows and a strip of ten link "bubbles" above them
   — is deleted, not restyled. The prose it carried lives in the add-in below, where a
   disclaimer belongs.

   The links keep their 44px finger box; the row is compact because there is ONE of it and the
   gaps are tight, not because the tap targets shrank.

   ── THE ADD-IN ──
   "Contact" is a Disclaimer/Policy-style entry sitting in the same row as Terms · Privacy ·
   Refunds · Risk, and it opens the panel below: what SFTi is (the prose that used to shout
   from the index header) and the direct channels (the four cards that used to be a whole
   page section). One affordance, one place, both public pages.

   ── TWO LAYERS ACROSS THE TOP, AND THEY DO DIFFERENT JOBS ──
   `::before` is the PHASE-OUT: a tint in the page's own canvas colour that fades IN over 140px,
   masked on the same curve so the blur has no edge. That is what removed the hard tonal step.
   `::after` is the ACCENT LINE (operator 2026-08-11: "there needs to be a similar divide line
   that is at the top of shop and index above the footer") — the SAME red→gold→silver gradient
   the header carries at its bottom edge, mirrored here at the footer's top edge.

   ★ THE TWO ARE NOT THE SAME THING AND THE DISTINCTION IS WHY BOTH EXIST. The footer's old
   `border-image` rule was ONE declaration doing both jobs: a gradient (decoration) AND a hard
   edge between two background tones (the defect the operator hated). Deleting it removed both.
   The tone step stays deleted — `::before` owns the transition — and the gradient returns on
   its own layer, as decoration on a continuous canvas. */

footer {
  position: relative;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  text-align: center;
  padding-top: 1.25rem;
  /* ── THE NAV CLEARANCE IS RESERVED ONCE PER SCROLLER, AND THIS IS THE DOCUMENT-FOOT CASE ──
     The nav is hollow and floats over the page (#201), so the last line needs clearance from it.
     On index, shop and the five /legal/ documents this footer IS the last element of the document
     and nothing else reserves anything, so the reserve belongs here. Inside the cockpit a box
     around it has already made the same reservation — `footer.in-shell` below is that case, and
     it is the reason this comment says ONCE rather than always. */
  /* ★★ THE INSET IS CONSUMED THE WAY THE NAV CONSUMES IT, AND THAT IS THE WHOLE OF THE FIX.
     `app/shared/css/nav.css` pays the home-indicator inset as `max(28px, env(...))` — 28px of OUR
     design margin that the inset only ADDS TO once it exceeds 28. This rule used to pay it as
     `5rem + env(...)`, a straight add. Two different arithmetics for one inset, so the two boxes
     drift apart by exactly the 28px the nav absorbs — and that difference is a void the operator
     can see (2026-08-12: "every page on index/ shop/ and system/ has too big of a gap between
     navbar and the content", two photos).

     MEASURED at 390x844, scrolled to the document foot, gap from the LAST PAINTED INK to the nav's
     first ICON (not its box — the box's top fades to alpha 0, so the band a human sees is bounded
     by the icons):

                          inset 0      inset 34 (his device)
       index/ · shop/     +14.9px      +40.2px      <- a void
       system/ (4 tabs)   -40..-64px   -46..-69px   <- ink passes UNDER the hollow nav, correct

     `5rem + max(28px, inset) - 28px` mirrors the nav term for term: 80px at inset 0, 86px at 34.
     ★ THE DESIGN MARGIN STAYS 5rem — ONLY THE INSET ARITHMETIC CHANGES, and that was the entire
     defect. A first pass took it to 4rem as well, which put the refresh control ON TOP OF the
     nav's SHOP icon on the operator's phone ("move the refresh button in index/ and shop/ up just
     a bit", 2026-08-12): −44px on his device where the surplus was only 28. Changing two things to
     fix one is how an over-correction gets mistaken for the repair — the inset term is the defect,
     the margin was never wrong. */
  padding-bottom: calc(5rem + max(28px, env(safe-area-inset-bottom, 0px)) - 28px);
  padding-left: max(5%, env(safe-area-inset-left, 0px));
  padding-right: max(5%, env(safe-area-inset-right, 0px));
}

/* ── THE COCKPIT'S HOST, AND WHY IT RESERVES AND INSETS NOTHING ───────────────────────
   `app/shared/js/footer.js` CREATES its host inside `#view-shop` when the document hangs no
   `#site-footer`, and stamps `in-shell` at that creation site — the branch already knows which
   case it is, so the class is a FACT about the host rather than a selector guessing at ancestry.
   That host lives inside `main.view-container`, and the two rules below undo exactly the two
   things that box has already done for its children:

   1 · IT HAS ALREADY RESERVED THE NAV'S CLEARANCE (`--nav-clearance`, app/system/css/shell.css).
       Paying it a second time here is not clearance, it is a void below the last line — the
       refresh control ends up floating above the nav instead of sitting in its hollow band the
       way it does on index and shop.
   2 · IT HAS ALREADY INSET ITS CHILDREN FROM THE FRAME, because it is the CARD COLUMN. This
       footer is not a card, it is the foot of the surface, and on index/shop it runs edge to
       edge — so the `::after` accent line must reach both screen edges here too. Giving back
       exactly the container's own side padding lands this on that box's PADDING edge, which is
       why the bleed cannot overflow: it is bounded by the very padding it undoes. */
footer.in-shell {
  padding-bottom: 0;
  margin-left: calc(-1 * max(var(--sp-md), var(--safe-left)));
  margin-right: calc(-1 * max(var(--sp-md), var(--safe-right)));
  /* THE OTHER HALF of the sticky-footer fix (app/system/css/shell.css's `.view-container`, same
     operator report 2026-08-20). This footer is that box's LAST flex child now; `margin-top: auto`
     is what actually claims the leftover space on a short view and pushes the footer down to the
     bottom of it, rather than letting it rest wherever the short content ends. On a view tall
     enough to fill the box there is no leftover space to claim, so this resolves to 0 and changes
     nothing — the footer already sat here. Scoped to `.in-shell` only: the public-page footer
     (`footer` alone, above) is the true last element of its OWN document, not a flex child of
     anything, and must not carry this. */
  margin-top: auto;
}

/* THE CUTOFF LINE BEHIND THE NAV (operator 2026-08-20: "the footers black should stretch behind
   the navbar to bottom.. they all are cutofd leaving a line and color change"). `footer::before`
   above anchors its own `bottom:0` to THIS element's border-box — correct for index/shop, where
   the footer's own `padding-bottom` already reserves the nav's clearance INSIDE that box. Here,
   rule #1 above zeroes that padding on purpose (the parent `.view-container` already reserves
   `--nav-clearance` once, in its own padding — shell.css), so the footer's box ends well short of
   the true screen bottom. `::before`'s tint+blur stops exactly there too, and `.view-container`
   paints no background of its own (confirmed live: transparent), so the reserved band below the
   footer shows `body`'s flat, unblurred `--bg-void` with no backdrop-filter over it — same base
   colour as the gradient's own final stop, but the hard blur edge is what actually reads as a
   seam, not a colour mismatch. Extending this pseudo-element's own box by the same
   `--nav-clearance` the parent already reserves carries the tint+blur the rest of the way down;
   the gradient/mask stops are percentage-based off this box's OWN height, so they still land in
   the same visual order over the taller box, they do not need re-tuning. */
footer.in-shell::before {
  bottom: calc(-1 * var(--nav-clearance));
}

footer::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -140px;
  bottom: 0;
  background: linear-gradient(180deg,
      rgba(10, 10, 15, 0.00) 0%,
      rgba(10, 10, 15, 0.16) 38%,
      rgba(10, 10, 15, 0.48) 64%,
      rgba(10, 10, 15, 0.80) 84%,
      rgba(10, 10, 15, 0.92) 100%);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.5) 40%, #000 72%, #000 100%);
          mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.5) 40%, #000 72%, #000 100%);
  z-index: -1;
  pointer-events: none;
}

/* ── THE ACCENT LINE, MIRRORED FROM THE HEADER (operator 2026-08-11, twice: "there needs to be a
      similar divide line that is at the top of shop and index above the footer" → then, pointing at
      two photos of the header: "the other two photos where me showing the line from the top that is
      needed at the bottom") ──

   THE GRADIENT IS THE HEADER'S, BYTE FOR BYTE, INCLUDING ITS DIRECTION. A reflected sweep
   (silver→gold→red) was the tempting choice and it is the wrong one: he asked for the line the
   header has, not a variation on it, and the two surfaces reading as one design depends on them
   being the same object at both ends of the page rather than a pair of near-misses. If this ever
   diverges from `app/shared/css/header.css`, that file is the original.

   ⚠ THE SAME TWO PROPERTIES ARE LOAD-BEARING HERE, for the same reason they are up there: it fades
   to alpha 0 at BOTH ends and never reaches the screen edge, and it sits on the continuous canvas
   `::before` already established rather than between two tones. An edge-to-edge rule at full alpha
   reads as a CUT, which is the exact defect the phase-out was built to remove — reinstating one at
   the footer would undo the fold from the other end.

   ★ AND IT SITS ABOVE `::before`, WHICH IS WHY BOTH LAYERS CAN EXIST AT ONE EDGE. `::before` is at
   z-index -1 and starts 140px ABOVE this line, so the tint has already faded in by the time the
   line is reached; the line is decoration ON that canvas, not the boundary of it. Same division of
   labour as the header, inverted. */
footer::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(90deg,
      rgba(230, 57, 70, 0.00)   0%,
      rgba(230, 57, 70, 0.55)  12%,
      rgba(212, 175, 55, 0.85) 42%,
      rgba(212, 175, 55, 0.85) 58%,
      rgba(192, 192, 192, 0.45) 82%,
      rgba(192, 192, 192, 0.00) 100%);
  box-shadow: 0 0 12px rgba(212, 175, 55, 0.30);
  z-index: 0;
  pointer-events: none;
}

/* THE SELECTOR IS THE ELEMENT, NOT A CLASS. index.html and shop.html hang
   <footer class="site-footer" id="site-footer"> for footer.js to fill, but the five /legal/
   documents carry their own hand-written <footer> with no class at all — and they link this
   card through app/shop/css/footer.css. Targeting the class dressed two of six surfaces and
   left the legal pages' footers unstyled: full-bleed, left-aligned, no fade. One selector,
   every footer. */
.foot-copy,
footer > p {
  font-size: 0.82rem;
  line-height: 1.45;
  max-width: 46ch;
}
footer > p { color: var(--text-secondary); }

/* THE © LINE IS GOLD (operator, 2026-08-11) — the whole line, in the company's own accent, and
   nothing beside it. The licence used to hang off this line as a second link; it is one of our
   documents like Terms and Privacy, so it sits in the link row below with them. */
.foot-copy { color: var(--accent-gold); }
.foot-copy strong { color: var(--accent-gold); font-weight: 600; }

/* ONE wrapped row. The old footer stacked two of these, each 44px tall and full-width
   justified, which is most of what "so spread out" was measuring. */
.foot-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0 0.15rem;
  max-width: 46ch;
}
.foot-links a,
.foot-links button {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.55rem;
  color: var(--accent-silver);
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  text-decoration: none;
  background: none;
  border: none;
  font-family: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) and (pointer: fine) {
  .foot-links a:hover,
  .foot-links button:hover { color: var(--accent-gold); }
}

/* ── THE DOCUMENT YOU ARE IN (operator 2026-08-11: "the file your in should be highlighted if
      your in one"). `footer.js` stamps `aria-current="page"` on the matching link. ──
   GOLD, and the SAME attribute `app/shared/css/nav.css` styles gold on the bottom nav — one
   convention answering "you are here" in both rows rather than two that can drift.
   ⚠ Weight is deliberately NOT bumped: these links sit on a 44px finger box in a wrapped row, and
   a bolder glyph re-flows the row on the current page only, so the footer would appear to shift
   as you navigate. Colour alone marks it and the geometry stays put. */
.foot-links a[aria-current="page"] {
  color: var(--accent-gold);
  text-shadow: 0 0 10px rgba(212, 175, 55, 0.35);
}

/* ═══ THE ADD-IN ═════════════════════════════════════════════════════════════════════ */

.addin {
  position: fixed;
  inset: 0;
  z-index: 10000;              /* over the floating nav (9999) — it owns the screen while open */
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(4, 4, 8, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  /* the dim and the card must leave TOGETHER — a backdrop that clears first leaves the card sliding
     against the live page, which is a second version of the flash rather than a fix for it */
  transition: opacity 0.32s ease;
}
.addin[hidden] { display: none; }
.addin.open { opacity: 1; }

.addin-card {
  width: min(100%, 620px);
  max-height: 86vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--glass-bg-heavy);
  border: 1px solid var(--glass-border-active);
  border-bottom: none;
  border-radius: 20px 20px 0 0;
  padding: 1.1rem 1.3rem calc(1.6rem + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -12px 48px rgba(0, 0, 0, 0.6);
  /* ── IT COMES FROM THE BOTTOM AND IT LEAVES THE SAME WAY (operator 2026-08-12: "every modal needs
        to come from the bottom of the page" · "it should just scroll down and disappear like the
        other modals") ──
     It was `translateY(14px)` — a 14px NUDGE, so the panel effectively appeared in place and the
     only thing that read as motion was the backdrop's fade. `100%` is the card's own height, so it
     starts entirely below the viewport bottom and rises off the edge, and REMOVING `.open` on close
     sends it back down the same path. That return trip is the "scroll down and disappear" — it
     comes free from the same two declarations, which is why the exit needed no separate rule.
     ⚠ THE CURVE IS `app/system/css/modals.css` §7.1's, VALUE FOR VALUE, and it is monotone for the
     reason stated there: a spring curve overshoots `translateY(0)` into NEGATIVE y and lifts the
     sheet off the bottom edge. Same geometry here, same answer. If that rule ever changes, IT is
     the original and this follows it. */
  transform: translateY(100%);
  transition: transform 0.32s cubic-bezier(0.32, 0.72, 0, 1);
}
.addin.open .addin-card { transform: translateY(0); }

/* ★★ THIS IS `.modal-grabber`, VALUE FOR VALUE (operator 2026-08-12: "its grey bar to grab and
   close need to be the same bar from the other modals with the same light up on touch effect —
   currently it is smaller and has a buggy light up effect").
   It WAS 40x4 silver-35% with `margin: 0 auto 0.9rem`; the app's sheets carry 52x5 white-42% with
   `margin: 10px auto 6px`. Three differences, and "smaller" is exactly the first two — measured off
   app/system/css/modals.css §7.1, not retyped from memory. If that rule ever changes, IT is the
   original and this follows it.

   ⚠ WHY THIS IS A COPY AND NOT A SHARED CLASS. `.modal-grabber` lives in modals.css, which is a
   SYSTEM-ONLY card — index.html and shop.html do not link it, and this panel opens on all three
   surfaces. Renaming this element to `.modal-grabber` would leave it completely unstyled on the two
   public pages. The alternative — hoisting the rule into a shared card — moves a rule the sheets own
   out from under them, which is a bigger edit than the operator asked for.

   ★ AND ONE HYPOTHESIS FOR "BUGGY" WAS MEASURED AND REFUTED, so nobody re-runs it: I expected iOS's
   default tap highlight to flash the card (`.addin-card` carries three touch listeners), suppressed
   in the app by `reset.css:22` but not on the public pages. It is suppressed there too —
   `app/index/css/reset.css:9` and `app/shop/css/reset.css:5` both set
   `-webkit-tap-highlight-color: transparent` on `html`, and the property inherits. That is not it.
   The size and colour ARE measured; a residual `:active` misbehaviour is not reproducible headlessly
   (`:active` needs a real finger) and is not claimed fixed here.

   The hover law below is modals.css's and the reason is the same: iOS Safari LATCHES `:hover` on the
   last-tapped element, so a hover paint outside `(hover: hover)` leaves the bar stuck lit after one
   tap. */
.addin-grabber {
  width: 52px;
  height: 5px;
  background: rgba(255, 255, 255, 0.42);
  border-radius: 3px;
  margin: 10px auto 6px;
  cursor: grab;
  flex-shrink: 0;
  transition: background 0.15s ease, transform 0.15s ease;
}
@media (hover: hover) {
  .addin-grabber:hover { background: rgba(255, 255, 255, 0.65); transform: scaleX(1.1); }
}
.addin-grabber:active { cursor: grabbing; background: rgba(255, 255, 255, 0.75); }

.addin-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.8rem;
  margin-bottom: 0.4rem;
}
.addin-title {
  font-family: 'Orbitron', monospace;
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: linear-gradient(90deg, var(--accent-gold), var(--accent-silver));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}
.addin-section { margin-top: 1rem; }
.addin-section h4 {
  font-family: 'Orbitron', monospace;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-gold);
  margin-bottom: 0.5rem;
}
.addin-section p {
  color: var(--text-secondary);
  font-size: 0.88rem;
  line-height: 1.55;
  margin-bottom: 0.6rem;
}
.addin-section strong { color: var(--text-primary); font-weight: 600; }
.addin-section a { color: var(--accent-gold); }

/* the direct channels — the contact cards, now rows inside the policy card */
.addin-channels {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.addin-channel {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-height: 44px;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  background: var(--glass-bg);
  color: var(--text-primary);
  font-size: 0.85rem;
  text-decoration: none;
  word-break: break-word;
}
.addin-channel .ch-icon {
  flex-shrink: 0;
  color: var(--accent-red);
  filter: drop-shadow(0 0 6px rgba(230, 57, 70, 0.4));
}
.addin-channel .ch-icon svg {
  width: 1.15rem; height: 1.15rem; display: block;
  stroke: currentColor; fill: none;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
/* img sits alongside svg, not in place of it — the extracted icon files (voice/sms/support/direct)
   bake their own color in now; see app/internal.svg/README.md. Only sizing carries over. */
.addin-channel .ch-icon img { width: 1.15rem; height: 1.15rem; display: block; }
.addin-channel .ch-label {
  font-family: 'Orbitron', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-gold);
  flex-shrink: 0;
  min-width: 8.5ch;
}
@media (hover: hover) and (pointer: fine) {
  .addin-channel:hover { border-color: var(--glass-border-active); }
}

body.addin-open { overflow: hidden; touch-action: none; }

@media (prefers-reduced-motion: reduce) {
  .addin, .addin-card { transition: none !important; }
}
