/* ══════════════════════════════════════════════════════════════════════════
   THE FOOTER

   F2 out of `/static/mockups/footer-lab-2.html`, picked 2026-09-10.

   WHY IT LOOKS LIKE THIS
   ──────────────────────
   What shipped before was four links and a copyright line at .78rem, centered,
   in `--text-muted` against the page's own white. It had no edge, so the page
   did not end so much as fade, and the footers it sits beside in this field
   run twenty-one to sixty-one links. It read as unfinished because it was the
   smallest in the field by a factor of five.

   The weight comes from three things and none of them is a big logo. A GROUND,
   so the page stops. CONTRAST, so the type reads as deliberate rather than
   provisional. And the ADDRESS, which is the highest substance-per-line thing
   available to us and which this site has never printed anywhere except
   clause 1 of the terms.

   WHAT IS DELIBERATELY NOT IN IT
   ──────────────────────────────
   The three nav destinations. Trips, Bucket list and Blog are in the bar on
   every page, and a footer repeating them is a directory of a site with three
   pages in it. What is left is the thing the bar cannot hold -- two ways to
   reach us -- and the paperwork.

   Every color is a `palette.css` variable. This file declares none, which is
   the rule that keeps one file in charge of what the brand looks like.
   ══════════════════════════════════════════════════════════════════════════ */

.site-footer {
    background: var(--brand-bg);
    color: var(--brand-text-muted);
    margin-top: 64px;
    padding: 30px 0 0;
}

.site-footer-in {
    max-width: 1080px;
    margin: 0 auto;
    padding: 0 28px;
}

.site-footer a, .site-footer-legal button { text-decoration: none; color: var(--brand-text-muted); }
.site-footer a:hover, .site-footer a:focus-visible,
.site-footer-legal button:hover, .site-footer-legal button:focus-visible { color: var(--brand-text); }
.site-footer-legal button { background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }

/* ── Row one: the mark, and the account ───────────────────────────────────
   The white logo unconditionally, because the ground is painted whatever the
   reader's mode is. Keying this to the mode is how a draft drew the ink mark
   on pine and made the case for the white file by breaking it. */
.site-footer-top {
    display: flex;
    align-items: center;
    gap: 18px;
    padding-bottom: 22px;
}
.site-footer-logo img { height: 28px; display: block; }

/* The account, on the far side of the mark. A ring rather than a bare glyph,
   because a lone icon on a wide painted row reads as a stray mark; the ring
   makes it a control. Sized here rather than trusting the 16px that
   lucide.createIcons stamps on every icon in the page. */
.site-footer-social { margin-left: auto; display: flex; gap: 10px; }
.site-footer-social a {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    border: 1px solid rgba(255,255,255,.22);
}
.site-footer-social a:hover, .site-footer-social a:focus-visible {
    border-color: var(--brand-text);
    background: rgba(255,255,255,.08);
}
/* The full text color, not the muted one, and a heavier stroke than the page
   default. Everything else in this footer is a word, where 72% opacity is a
   quieter voice; a glyph has no counters or stems to carry meaning if you lose
   the line, so the same treatment that reads as "quieter" on type reads as
   "smudged" here. base.html stamps stroke-width 1.5 on every icon in the page,
   which is right at 16px inside a line and too thin at 19 on a dark ground. */
.site-footer-social a { color: var(--brand-text); }
/* A filled glyph, not a stroked one: the Font Awesome mark is a single path
   with fill="currentColor", so the stroke-width the rest of this site's icons
   are drawn with does nothing here. */
.site-footer-social svg {
    width: 18px;
    height: 18px;
    fill: currentColor;
    display: block;
}

/* ── Row two: who we are, and the paperwork ───────────────────────────────── */
.site-footer-bot {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
    align-items: flex-end;
    padding: 18px 0 22px;
    border-top: 1px solid rgba(255,255,255,.14);
    font-size: .79rem;
}

.site-footer-id { display: flex; flex-direction: column; gap: 2px; }

.site-footer-mail {
    font-size: .86rem;
    font-weight: 600;
    color: var(--brand-text) !important;
    margin-bottom: 6px;
}

/* The body face, not the mono one. An earlier draft set this in mono at
   .7rem, which is right where a registration reads as a data row and wrong
   here: it ran wide enough to break after the word VAT and drop the number
   onto a line of its own. It is an address. */
.site-footer-co { line-height: 1.65; font-style: normal; }
.site-footer-co b { color: var(--brand-text); font-weight: 700; }
.site-footer-co .sep { opacity: .45; padding: 0 6px; }

.site-footer-legal {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    margin-left: auto;
    align-items: baseline;
}

.site-footer-year { opacity: .7; }

/* ── The phone ────────────────────────────────────────────────────────────
   The legal row stops being right-aligned, because there is nothing to align
   against once the identity block has taken the full width. */
@media (max-width: 720px) {
    .site-footer { margin-top: 44px; padding-top: 24px; }
    .site-footer-in { padding: 0 20px; }
    .site-footer-bot { gap: 16px; }
    .site-footer-legal { margin-left: 0; gap: 12px; }
}

/* ── The newsletter ───────────────────────────────────────────────────────
   Between the mark and the paperwork, because it is the one thing on this
   ground somebody can do rather than read. The field sits on a wash of the
   text color rather than in a white box: a white input on pine would be the
   loudest thing on the page, and this is an offer rather than a demand. The
   button is gold, which is the brand's one color for "act here". */
.site-footer-news {
    display: flex;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
    padding: 18px 0 20px;
    border-top: 1px solid rgba(255,255,255,.14);
}
.site-footer-news-copy { display: flex; flex-direction: column; gap: 2px; font-size: .82rem; }
.site-footer-news-copy b { color: var(--brand-text); font-size: .95rem; font-weight: 700; }

.site-footer-news-field { margin-left: auto; display: flex; gap: 8px; flex: 0 1 390px; min-width: 0; }
.site-footer-news-field input {
    flex: 1;
    min-width: 0;
    height: 42px;
    padding: 0 16px;
    border-radius: 999px;
    border: 1px solid rgba(255,255,255,.22);
    background: rgba(255,255,255,.08);
    color: var(--brand-text);
    font: inherit;
    font-size: .88rem;
}
.site-footer-news-field input::placeholder { color: var(--brand-text-muted); }
.site-footer-news-field input:focus { outline: none; border-color: var(--brand-text); background: rgba(255,255,255,.12); }
.site-footer-news-field button {
    height: 42px;
    padding: 0 20px;
    border: 0;
    border-radius: 999px;
    cursor: pointer;
    background: var(--brand-highlight);
    color: var(--brand-highlight-text);
    font: inherit;
    font-size: .88rem;
    font-weight: 700;
    white-space: nowrap;
}
.site-footer-news-field button:hover, .site-footer-news-field button:focus-visible { filter: brightness(1.07); }

/* For a screen reader, which needs the label a sighted reader gets from the
   placeholder and the line beside it. */
.site-footer-news-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

@media (max-width: 720px) {
    .site-footer-news-field { margin-left: 0; flex-basis: 100%; }
}

/* What the newsletter field answers (`newsletter/_sent.html`), in the dialog
   the field opens. It leads with a photograph from the bucket list, because a
   card saying "check your inbox" is the least interesting thing the site can
   show somebody who just asked to hear more. */
.nl-photo { margin: 14px 0 0; aspect-ratio: 16 / 9; overflow: hidden; }
.nl-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.nl-text { padding: 16px 20px 20px; color: var(--text-secondary); line-height: 1.6; font-size: .92rem; }
.nl-text p { margin: 0 0 10px; }
.nl-text p:last-child { margin-bottom: 0; }
.nl-text strong { color: var(--text-primary); font-weight: 600; }
.nl-small { font-size: .84rem; color: var(--text-muted); }
.nl-small a, .nl-core a:not(.nl-btn) { color: var(--accent-color); }
.nl-upsell { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border-color); }
.nl-upsell .nl-btn { display: block; text-align: center; padding: 11px 20px; }

/* The pages the newsletter leads to (`newsletter/status.html`): the answer in
   the middle and the bucket list flying out around it on an ellipse. Each
   photograph knows only its place in the ring (--i of --n) and a small tilt;
   the angle and the radius are worked out here, so the template stays a list. The
   footer goes, because its own signup field under a signup page asks twice. */
body.nl-stage-page footer { display: none; }
.nl-stage {
    --rx: min(40vw, 560px);
    --ry: min(34vh, 300px);
    --size: clamp(84px, 11vw, 150px);
    position: relative; overflow: hidden;
    min-height: calc(100vh - 64px);
    display: flex; align-items: center; justify-content: center;
    padding: 40px 16px;
}
.nl-orbit { position: absolute; inset: 0; pointer-events: none; }
.nl-orbit img {
    --a: calc(360deg / var(--n) * var(--i) - 90deg);
    position: absolute; left: 50%; top: 50%;
    width: var(--size); aspect-ratio: 4 / 5; object-fit: cover;
    border-radius: 14px; border: 4px solid var(--card-bg);
    box-shadow: var(--shadow-card), 0 18px 40px var(--card-shadow);
    transform: translate(-50%, -50%)
               translate(calc(cos(var(--a)) * var(--rx)), calc(sin(var(--a)) * var(--ry)))
               rotate(var(--tilt));
    animation: nl-fly-out .9s cubic-bezier(.2, .8, .2, 1.15) both,
               nl-drift 6s ease-in-out .9s infinite alternate;
    animation-delay: calc(var(--i) * 45ms), calc(.9s + var(--i) * 45ms);
}
@keyframes nl-fly-out {
    from { opacity: 0; transform: translate(-50%, -50%) scale(.2) rotate(0deg); }
}
@keyframes nl-drift {
    to { translate: 0 -8px; }
}
.nl-core {
    position: relative; z-index: 1;
    width: 100%; max-width: 440px; text-align: center;
    padding: 32px 28px; border-radius: 20px;
    background: var(--card-bg); box-shadow: 0 24px 70px var(--card-shadow);
    color: var(--text-secondary); line-height: 1.6;
}
.nl-core h1 { font-size: 1.75rem; font-weight: 800; letter-spacing: -.02em; line-height: 1.2; margin: 0 0 12px; color: var(--text-primary); }
.nl-core p { margin: 0 0 18px; }
.nl-core strong { color: var(--text-primary); font-weight: 600; }
.nl-core .nl-text { padding: 0; font-size: 1rem; }
.nl-btn {
    display: inline-block; border: 0; cursor: pointer;
    padding: 13px 28px; border-radius: 999px;
    background: var(--accent-gradient); color: var(--accent-text);
    font: inherit; font-weight: 700; text-decoration: none;
}
.nl-btn:hover { filter: brightness(1.08); color: var(--accent-text); }
.nl-quiet { display: block; margin-top: 14px; font-size: .88rem; }

/* A phone: a taller, narrower ring behind the card, and eight rather than twelve. */
@media (max-width: 700px) {
    .nl-stage { --rx: 44vw; --ry: 40vh; --size: 76px; }
    .nl-orbit { --n: 8 !important; }
    .nl-orbit img:nth-child(n+9) { display: none; }
    .nl-core { padding: 26px 20px; }
}
@media (prefers-reduced-motion: reduce) {
    .nl-orbit img { animation: none; }
}
