/* ==========================================================================
   STYLE.CSS — layout & look of the "Coming Soon" page specifically
   ==========================================================================

   This file is written MOBILE-FIRST. That means:
     - Every rule below with NO @media wrapper is the phone-screen version.
     - Each `@media (min-width: ...)` block further down OVERRIDES a few
       properties once the screen is at least that wide, to make better use
       of the extra space on tablets/laptops/desktops.

   Reading order top-to-bottom = layout order top-to-bottom on the page:
   page background -> page shell -> header/logo -> hero text -> button ->
   footer -> birthday pop-up (a fixed overlay, independent of the flow above).

   Every color/size/spacing value here is a `var(--token-name)` pulled from
   tokens.css — see that file if you want to know what a value actually is.
   ========================================================================== */


/* --------------------------------------------------------------------------
   PAGE BACKGROUND — the full-bleed hero photo
   Lives on <body> rather than `.page`, on purpose: `.page` gets a max-width
   at desktop (below) so its CONTENT doesn't stretch edge-to-edge on huge
   monitors, but we still want the PHOTO to cover the entire browser window
   no matter how wide it is. Putting the background one level up, on <body>,
   gives us both at once.

   This intentionally overrides the design system's general "no photo as a
   full-page background" rule, specifically for this page, per request. A
   dark gradient is painted BETWEEN the photo and the page content so
   headline/countdown text stays readable on top of it. Backgrounds paint in
   the order listed, first-on-top — so the gradient (listed first) sits
   visually above the photo (listed second).

   On phones (this base rule) the text column runs nearly full-width, so the
   scrim is a flat, fairly dark wash across the whole image — enough
   contrast for white text anywhere on the page. Wider screens get a
   left-to-right version below, matching the original mockup: dark behind
   the text on the left, fading out so the photo reads clearly on the right
   where there's no text over it. */
body {
  min-height: 100svh; /* "small viewport height" — full screen height, safe on mobile browser UI */
  /* LIGHT TREATMENT: the hero image is bright, so instead of the old dark
     scrim we lay a soft WARM-WHITE wash over it — enough to keep the dark
     text readable, light enough that the celebratory "21" still shows. The
     background-color fallback is cream too, so if the image is slow to load
     the page stays light (not dark) and the dark text never disappears. */
  background-color: #F6F1E7;
  /* MOBILE: a top-to-bottom wash — strong behind the text up top, clearing
     lower down so the "21" shows through in the empty space beneath the
     content, then a little wash again at the very bottom to keep the footer
     legible. */
  background-image:
    linear-gradient(180deg,
      rgba(250,247,240,.92) 0%,
      rgba(250,247,240,.86) 42%,
      rgba(250,247,240,.55) 60%,
      rgba(250,247,240,.12) 80%,
      rgba(250,247,240,.34) 100%),
    url("../images/hero-background.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* --------------------------------------------------------------------------
   PAGE SHELL
   `.page` is the layout wrapper in index.html — it stacks header/hero/
   footer top to bottom and pushes the footer down even on a tall, mostly-
   empty phone screen. It no longer carries the background itself (that's
   on <body> now, see above) — it's purely a layout + max-width container.
   -------------------------------------------------------------------------- */
.page {
  position: relative; /* establishes the positioning context other elements sit against */
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  padding: var(--space-6) var(--space-5); /* 24px top/bottom, 20px sides on phones */
}


/* --------------------------------------------------------------------------
   PAGE-ENTER MOTION
   A one-time, top-to-bottom reveal when the page first loads: the header
   settles in slightly before the hero content follows. This is the ONLY
   place motion has a real ongoing presence on this page (declared dial:
   MOTION 2 — a single staggered entrance, not a full choreographed
   sequence). Everywhere else stays MOTION 1 (hover/press feedback only) —
   see the birthday pop-up's confetti further down for the one deliberate
   exception, which explains its own dial there.

   Why animate at all (R-19 — motion needs a written purpose): it draws the
   eye in the same order a person would naturally read the page (logo ->
   headline), instead of the whole page just snapping into existence at
   once. It runs exactly once per page load — never loops.

   Reduced motion: `--dur-slow` becomes 0ms automatically under
   `prefers-reduced-motion: reduce` (see that override up in tokens.css).
   A 0ms keyframe animation just jumps straight to its end state, so
   reduced-motion visitors see the finished layout immediately with no
   perceptible movement — no separate media query needed here for that. */
@keyframes enter-fade-rise {
  from {
    opacity: 0;
    transform: translateY(14px); /* starts slightly below its resting spot */
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* --------------------------------------------------------------------------
   HEADER — logo + tagline
   -------------------------------------------------------------------------- */
.site-header {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);

  /* `both` keeps the pre-animation state (opacity: 0) applied before the
     animation starts, and the end state after it finishes — otherwise the
     header would flash fully visible for one frame before animating. */
  animation: enter-fade-rise var(--dur-slow) var(--ease-out) both;
}

.logo-link {
  display: inline-flex; /* shrinks the clickable/focusable area to fit the image exactly */
}

.logo {
  height: 28px;
  width: auto;
  display: block;
}

/* The thin vertical line between the logo and the tagline, like the mockup.
   `aria-hidden="true"` is set on it in the HTML since it's purely visual. */
.header-divider {
  width: 1px;
  height: 24px;
  background: var(--border-strong);
}

.tagline {
  font-family: var(--font-display);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-body-sm);
  line-height: 1.25;
  color: var(--text-primary);
  text-shadow: 0 1px 8px rgba(0, 0, 0, .7); /* see the note on .hero below */
}

.tagline .accent { color: var(--text-accent); }


/* --------------------------------------------------------------------------
   HERO — the big "Coming Soon" moment
   `.hero` grows to fill the leftover vertical space and centers its content
   in that space, so the block sits mid-page instead of glued to the header.
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  z-index: 1;
  flex: 1;                    /* take up all the room .site-header and .site-footer don't use */
  display: flex;
  flex-direction: column;
  /* MOBILE: push the text up to the top so the lower part of the screen is
     free for the "21" background to show through (see the clearing gradient
     on <body> above). Desktop re-centers it in the ≥900px block below. */
  justify-content: flex-start;
  gap: var(--space-6);
  max-width: 640px;           /* keeps text lines from stretching unreadably wide on desktop */
  padding-block: var(--space-9);

  /* A soft dark shadow directly behind every letter, as a contrast safety
     net independent of exactly what photo pixel happens to sit behind the
     text. `text-shadow` is inherited automatically, so this one line
     covers .headline, .lede, and the pine-colored .accent spans inside
     them too — no need to repeat it on each. Why this matters: the dark
     overlay on <body> intentionally fades out toward the right edge on
     wide screens (see the "PAGE BACKGROUND" comment near the top of this
     file) so the photo stays visible there — but that also means text
     wrapping close to that fade zone gets less overlay protection. This
     shadow keeps it readable either way, without needing to darken the
     whole photo more than the design calls for. */
  text-shadow: 0 2px 12px rgba(0, 0, 0, .65);

  /* Same entrance as .site-header (see the keyframe + explanation up
     there), started 120ms later — small enough to read as "the same
     moment," large enough that the eye catches the header settle first,
     then the headline. That 120ms offset is the only thing different
     between the two; duration and easing stay identical on purpose, so
     it reads as one coordinated reveal, not two unrelated animations. */
  animation: enter-fade-rise var(--dur-slow) var(--ease-out) 120ms both;
}

.headline {
  font-family: var(--font-display);
  font-weight: 800; /* extra-bold — a punchier "COMING SOON" */
  text-transform: uppercase;
  letter-spacing: var(--tr-display);
  line-height: var(--lh-tight);
  /* clamp(MIN, PREFERRED, MAX) = fluid font size: it scales smoothly with
     the viewport width but never goes below/above these bounds. This is
     what makes the huge mockup headline shrink gracefully on a small phone
     instead of overflowing the screen. */
  /* Bigger, and scaled to fill the width on a phone: "COMING" stretches
     nearly edge-to-edge on a small screen, then caps out on desktop. 21vw
     is tuned so the longest word fills the width without spilling past the
     edge (which would cause a horizontal scrollbar). */
  font-size: clamp(3.25rem, 21vw, 7rem);
}

.lede {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body);
  color: var(--text-body);
  max-width: 46ch; /* "ch" = roughly one character width — caps the paragraph's measure for readability */
}

.lede .accent {
  color: var(--text-accent);
}


/* --------------------------------------------------------------------------
   DIVIDER — the short accent line above the button, like the mockup
   -------------------------------------------------------------------------- */
.divider-line {
  width: 32px;
  height: 2px;
  background: var(--pine-300);
  border: none;
  border-radius: var(--radius-pill);
}


/* --------------------------------------------------------------------------
   BUTTON — pill shape with the brand's signature "leading dot" arrow
   -------------------------------------------------------------------------- */
.btn {
  position: relative; /* gives .btn-invite-pulse::after (below) something to anchor to */
  align-self: flex-start;     /* don't stretch full-width on mobile — hug the text */
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--pad-control-y) var(--pad-control-x);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-weight: var(--fw-medium);
  font-size: var(--fs-body-sm);
  letter-spacing: var(--tr-label);
  white-space: nowrap;
  cursor: pointer;
  transition:
    background var(--dur-base) var(--ease-out),
    transform var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}

.btn:active {
  transform: scale(var(--press-scale));
}

.btn-primary {
  background: var(--bg-accent);
  color: var(--text-on-accent);
  border: 1px solid transparent;
  box-shadow: var(--shadow-accent);
}

.btn-primary:hover {
  background: var(--bg-accent-hover);
}

.btn-dot {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: var(--radius-pill);
  background: #fff;
  color: var(--bg-accent);
  transition: transform var(--dur-base) var(--ease-out);
}

/* The little arrow rotates 45° on hover — a signature detail from the
   design system's Button component. */
.btn:hover .btn-dot {
  transform: rotate(45deg);
}

/* INVITE PULSE — a single soft glow around the Follow button, right after
   the birthday pop-up closes (see closeBirthdayMessage() in birthday.js).
   Purpose: a gentle affordance hint back toward the one real action on
   this page, timed to the moment attention naturally returns to it —
   not a generic "look at me" attention-grabber that runs on its own.

   Plays exactly once (JS removes the class on animationend, see
   birthday.js) and never loops or repeats on its own. Opacity only, on a
   separate pseudo-element behind the button — the button itself never
   moves or resizes, so it can't feel like nagging. */
.btn::after {
  content: "";
  position: absolute;
  inset: -8px;
  border-radius: var(--radius-pill);
  background: radial-gradient(circle, rgba(79, 177, 152, .55) 0%, rgba(79, 177, 152, 0) 72%);
  pointer-events: none;
  opacity: 0;
}

.btn.invite-pulse::after {
  animation: invite-pulse 1500ms var(--ease-out) 1;
}

@keyframes invite-pulse {
  0% { opacity: 0; }
  35% { opacity: 1; }
  100% { opacity: 0; }
}


/* --------------------------------------------------------------------------
   FOOTER
   -------------------------------------------------------------------------- */
.site-footer {
  position: relative;
  z-index: 1;
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  /* --text-faint was too low-contrast here (~3.7:1 against the dark
     background — WCAG AA needs 4.5:1 for text this small). --text-muted
     is a lighter gray that clears that bar comfortably (~6:1). */
  color: var(--text-muted);
  /* Extra safety net regardless of what's directly behind this text — see
     the note on .hero above for why every text block over the photo has one. */
  text-shadow: 0 1px 8px rgba(0, 0, 0, .7);
}


/* --------------------------------------------------------------------------
   BIRTHDAY POP-UP
   A personal surprise that pops in shortly after the page loads (see
   assets/js/birthday.js), sitting on top of everything else. Hidden by
   default via opacity/visibility so it can fade AND scale in smoothly —
   the `hidden` HTML attribute can't be transitioned, so we don't use it.
   -------------------------------------------------------------------------- */
.birthday-overlay {
  position: fixed;
  inset: 0; /* shorthand for top:0; right:0; bottom:0; left:0 — covers the whole viewport */
  z-index: 100; /* above everything else on the page (hero content sits at z-index 1) */
  display: grid;
  place-items: center; /* centers the card both horizontally and vertically */
  padding: var(--space-5);
  background: rgba(7, 7, 7, .78);
  backdrop-filter: blur(6px); /* softly blurs the page behind the overlay */

  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--dur-slow) var(--ease-out),
    visibility 0s linear var(--dur-slow); /* wait until the fade finishes before fully hiding */
}

/* JS adds this class to trigger the entrance; removing it reverses it. */
.birthday-overlay.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--dur-slow) var(--ease-out);
}

.birthday-card {
  position: relative;
  width: 100%;
  max-width: 440px;
  padding: var(--pad-card-lg);
  background: var(--bg-raised);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-raised);
  text-align: center;

  /* The actual "pop": starts slightly small and transparent, then settles
     into place. Runs on a slightly longer, custom duration (480ms) rather
     than the standard --dur-slow token, so this one special celebratory
     moment feels a touch more deliberate than everyday hovers/transitions. */
  transform: scale(.85);
  opacity: 0;
  transition: transform 480ms var(--ease-entrance), opacity 480ms var(--ease-entrance);
}

.birthday-overlay.is-open .birthday-card {
  transform: scale(1);
  opacity: 1;
}

/* A soft warm wash that blooms in behind the card, arriving a beat after
   the card itself pops in — ties the confetti + card into one warm moment
   instead of two unrelated effects. Opacity only (no movement, no size
   change), so it stays cheap to animate and needs no separate
   reduced-motion override: --dur-slow already collapses to 0ms for
   reduced-motion visitors via the token override in tokens.css, which
   just means the glow appears instantly instead of blooming in — exactly
   the right reduced-motion behavior (no motion, same end result). */
.birthday-card::before {
  content: "";
  position: absolute;
  inset: -40px;
  background: radial-gradient(60% 60% at 50% 40%, rgba(79, 177, 152, .35) 0%, rgba(79, 177, 152, 0) 70%);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}

.birthday-overlay.is-open .birthday-card::before {
  opacity: 1;
}

.birthday-heading {
  font-family: var(--font-display);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-h2);
  letter-spacing: var(--tr-display);
  color: var(--text-primary);
  margin-bottom: var(--space-4);
}

.birthday-message {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-relaxed);
  color: var(--text-body);
}


/* --------------------------------------------------------------------------
   CONFETTI — the one deliberately loud moment on this whole page
   ---------------------------------------------------------------------
   Declared dial: MOTION 3 (choreographed), ENERGY 3 (bold) — a one-time,
   intentional exception to the calm MOTION 1 the rest of the page holds
   to (R-31: written reason for the exception). This is a personal
   birthday surprise, not a generic UI moment, so it's allowed to be more
   alive than a button hover — the celebration IS the point here.

   What it is NOT: an "AI Powered"-style sparkle/glow effect, and not a
   literal trumpet or party-popper icon — a decorative icon with no real
   connection to EddyReady's brand would just be a different flavor of
   generic AI slop. Instead, the burst is built from small rectangles in
   the site's OWN brand colors (Pine + white) — same "no second hue" rule
   the rest of the page follows, just with more energy behind it.

   Each piece (`.confetti-piece`) is a tiny <span>, created and positioned
   by assets/js/birthday.js right as the card pops in, then removed after
   it finishes falling — this plays exactly ONCE per pop-up open and never
   loops (antislop explicitly bans endless decorative motion). JS also
   skips creating any of this entirely for visitors with
   prefers-reduced-motion set — see birthday.js for that check; there's
   no reduced-motion override needed here in the CSS because the pieces
   simply never get created in the first place. */
.confetti {
  position: absolute;
  inset: 0;
  overflow: visible; /* pieces are allowed to fly outside the card's own edges */
  pointer-events: none; /* purely decorative — never intercepts clicks/taps */
}

.confetti-piece {
  position: absolute;
  top: -6px; /* starts just above the card, near where it "pops" in from */
  /* left, background, and the two custom properties below are all set
     per-piece from JS (--confetti-drift, --confetti-spin) so every piece
     flies a slightly different way — see spawnConfetti() in birthday.js. */
  width: 6px;
  height: 14px;
  border-radius: 1px;

  /* Only transform + opacity animate here — the two properties that stay
     cheap for the browser to animate (no layout recalculation involved),
     per the motion performance rule this was built against. */
  animation: confetti-fall var(--confetti-duration, 1300ms) var(--ease-out) var(--confetti-delay, 0ms) both;
}

@keyframes confetti-fall {
  0% {
    transform: translate(0, 0) rotate(0deg);
    opacity: 1;
  }
  100% {
    /* --confetti-drift (sideways) and --confetti-spin (rotation) come from
       JS, so this keyframe is shared by every piece while each one still
       moves uniquely. --confetti-fall-distance defaults to 130px, which
       comfortably clears the pop-up card's height; the afterglow pieces
       (falling from the top of the whole viewport, not a small card)
       override it to something larger — see the two rules above. */
    transform: translate(var(--confetti-drift, 0px), var(--confetti-fall-distance, 130px)) rotate(var(--confetti-spin, 360deg));
    opacity: 0;
  }
}

/* --------------------------------------------------------------------------
   AFTERGLOW — a few pieces spill onto the main page as the pop-up closes
   ---------------------------------------------------------------------
   Purpose: preventing a jarring change. Without this, the celebration
   just stops the instant the dialog closes — one moment there's confetti,
   the next it's gone. A handful of pieces continuing to drift onto the
   page bridges that, so the mood trails off instead of cutting off.

   Deliberately smaller and calmer than the pop-up's own burst (see
   PIECE_COUNT in spawnAfterglow() in birthday.js) — this is the
   celebration settling down, not a second show. Same rules as the main
   burst: transform/opacity only, plays once, brand colors only, skipped
   entirely under prefers-reduced-motion, pieces self-remove after
   falling. Fixed positioning (not absolute) because this sits on <body>,
   not inside a card. */
.confetti-afterglow {
  position: fixed;
  inset: 0;
  overflow: visible;
  pointer-events: none;
  z-index: 90; /* below the pop-up (100) in case it's still fading out, above the page content (1) */
}

.confetti-afterglow .confetti-piece {
  top: -14px; /* starts just above the very top of the viewport, not a card */
  --confetti-fall-distance: 340px; /* the viewport is much taller than the card — let pieces travel further */
  /* Reuses the same confetti-fall keyframe automatically (inherited from
     the base .confetti-piece rule) — the calmer pace comes from JS giving
     these pieces longer --confetti-duration/--confetti-delay values, see
     spawnAfterglow() in birthday.js. */
}

.birthday-close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  /* 44x44px is the minimum comfortable tap target for a touchscreen —
     it was 32x32px before, which is fine for a mouse cursor but too
     small to reliably hit with a thumb. The × glyph itself stays the
     same visual size (font-size below is unchanged); only the invisible
     clickable area around it grows. */
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-subtle);
  background: transparent;
  color: var(--text-muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  transition:
    background var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

.birthday-close:hover {
  background: var(--bg-ghost-hover);
  color: var(--text-primary);
}

/* Press feedback, matching the same shrink used on the main CTA button
   (.btn:active above) — this button was missing that third state. */
.birthday-close:active {
  transform: scale(var(--press-scale));
}


/* ==========================================================================
   RESPONSIVE BREAKPOINTS
   Mobile-first: base rules above already work on any screen size. These
   just take advantage of extra space once it's available.
   ========================================================================== */

/* Small tablets and larger phones in landscape */
@media (min-width: 640px) {
  .page {
    padding: var(--space-8) var(--space-9);
  }

  .logo { height: 32px; }

  .hero { gap: var(--space-7); }
}

/* Tablets and small laptops */
@media (min-width: 900px) {
  /* Now that the text column (.hero, max-width below) no longer spans the
     full screen, switch the scrim to a left-to-right fade: strong over the
     text on the left, easing away so the photo shows clearly on the right
     — matching the original mockup's composition. Still on <body>, so it
     stays full-width no matter how wide the window gets.

     The minimum (rightmost) opacity is .78 — measured, not guessed: the
     actual photo has a genuine near-white highlight (rgb 255,253,246,
     sampled directly from the file) sitting in this exact region on wide
     screens. Checked against real text colors with the WCAG contrast
     formula, .78 is the darkest this can safely go — anything lower and
     the pine-colored accent words in the paragraph drop below the
     3:1 minimum for large text right where that highlight sits. `.page`
     is centered on very wide monitors (see the 1200px+ breakpoint below),
     so the exact pixel position where the text column ends keeps shifting
     as the window gets wider, which is why the floor has to hold up
     everywhere, not just at one specific width. Combined with the
     text-shadow on .hero/.tagline/.site-footer above, this keeps things
     readable with a real safety margin instead of a hopeful guess. */
  body {
    /* LIGHT TREATMENT on wide screens: a left-biased warm-white wash — near
       opaque behind the text on the left, clearing toward the right so the
       bright "21" and crown stay vivid where there's no text over them. */
    background-image:
      linear-gradient(100deg,
        rgba(250,247,240,.90) 0%,
        rgba(250,247,240,.72) 34%,
        rgba(250,247,240,.30) 58%,
        rgba(250,247,240,0) 82%),
      url("../images/hero-background.jpg");
  }

  .page {
    padding: var(--space-9) var(--space-12);
  }

  .hero {
    max-width: 680px;
    padding-block: var(--space-11);
    /* Desktop re-centers the content vertically (mobile top-aligns it). */
    justify-content: center;
  }
}

/* Desktop */
@media (min-width: 1200px) {
  .page {
    /* Keep CONTENT readable on very wide monitors: centre a max-width
       column instead of letting text stretch edge-to-edge. The background
       photo on <body> is unaffected by this and still spans the full
       browser width. */
    max-width: var(--page-max);
    margin-inline: auto;
    padding-block: var(--space-11);
  }
}


/* ==========================================================================
   LIGHT TREATMENT — text + logo overrides for the bright "21" background
   ==========================================================================
   The rules above (and in tokens.css) were built for a DARK hero: white
   text with dark shadows. The background is now a bright image, so this
   block flips the text to warm-dark, drops the dark shadows, and darkens
   the logo. Kept as one clearly-labelled block at the end so it's easy to
   find or undo. Warm grays (brown-tinted) match the rest of the brand.
   -------------------------------------------------------------------------- */

/* Logo: the SVG art is near-white; darken it to warm ink so it reads on the
   light background. (Same filter trick used on the form/wall pages.) */
.logo {
  /* The MAIN logo already has dark text + a green mark made for a light
     background, so no color filter is needed (unlike the old white logo). */
  filter: none;
}

/* Tagline (top-right): warm dark, no shadow; its accent word stays green but
   steps to the darker Pine that reads on a light background. */
.tagline {
  color: #2B2621;
  text-shadow: none;
}
.tagline .accent { color: var(--pine-500); }

/* Hero text: remove the dark shadow that existed only for the dark photo. */
.hero { text-shadow: none; }

/* Headline: warm near-black. A faint WHITE glow keeps the big letters crisp
   if they ever overlap a busier part of the image. */
.headline {
  color: #241F1B;
  text-shadow: 0 1px 10px rgba(250, 247, 240, .6);
}

/* Body paragraph: warm dark; its highlighted phrases use the darker Pine. */
.lede { color: #4C443C; }
.lede .accent { color: var(--pine-500); }

/* Footer: warm muted, no shadow. */
.site-footer {
  color: #7C7266;
  text-shadow: none;
}
