/* =============================================================================
   announce.css  --  the hero "announcement" typography and the pricing offer.
   Split out of mnb-theme.css, which had grown past 3,500 lines and made every
   small tweak a hunt.

   WHAT LIVES HERE
     - the three-line hero on the features page (SCAN * SIGN * DONE, the typing
       line, the 10 SECONDS payoff) with its melt, slide-in and reflection
       animations
     - .mnb-hero-band, the plate and drop shadow behind them
     - the pricing page's "switch to annual" offer pill
     - every @keyframes those need

   WHERE IT LOADS
     includes/header.php links this only on the pages that use it -- features,
     pricing, download and login. The last two carry a lone .mnb-hero-claim for
     their "Coming soon" lines, which is why they are on the list.

   CAUTION
     .mnb-hero-claim base rules moved here too, so a new page using that class
     must be added to the list in header.php or its hero will render unstyled.
   ============================================================================= */

/* PITCH TITLE (features page). A modifier, not a change to .mnb-page-title --
   that class is shared by all 51 jurisdiction pages plus support, download and
   login, so recolouring it directly would repaint the whole site.

   Red in light, gold in dark (Jordan 2026-08-05). #C8102E is a flag red: it
   reads as emphasis rather than as an error state, pairs with the brand gold
   without competing, and clears 6:1 contrast on the light background. Dark
   mode uses the existing --mnb-gold, since a saturated red on charcoal
   vibrates and gold is already the site's accent there.

   The mirror reflection inherits colour from this rule automatically -- ::after
   paints the same text, so nothing extra is needed. */
/* The PITCH LINE, not the page title -- .mnb-hero-claim is the centred
   headline under the breadcrumb ("Scan, sign, done..."). Scoped to the
   features page because the same class carries the "Coming soon" lines on
   download and login, where red would read as an error rather than emphasis.

   #C8102E is a flag red: emphasis, not an error state, which matters on a site
   that already uses red medallions for "not accepted". It pairs with the brand
   gold without competing and clears 5.6:1 on the light background. Dark mode
   uses the gold instead -- saturated red on charcoal vibrates. The mirror
   reflection inherits the colour automatically via ::after. */
/* STACKED PAIR. Two lines each need their OWN reflection, and one element can
   only produce one: ::after renders attr(data-text), which comes from
   textContent -- and textContent drops <br>, so a single element with a break
   reflects both lines as one long string. Hence two paragraphs.

   The seam between them is tightened with a negative top margin rather than by
   shrinking the first element's bottom margin, because that bottom margin is
   what reserves room for line one's reflection. Net gap: 36px desktop, 28px
   mobile -- enough for the flipped copy, not enough to read as two blocks. */
/* Read as ONE block broken by a <br>, not two paragraphs: the seam closes to
   ordinary line spacing while the outer margins stay put -- 44px above the
   first line, 66px below the second.
   :has() picks the FIRST of a pair so only its bottom margin collapses; the
   second keeps the full bottom margin that reserves room for its reflection.
   The small residual gap (0.3em) is deliberate -- with zero, the first line's
   reflection paints over the second line's caps. */
[data-page="features"] .mnb-hero-claim--melt { margin-bottom: calc(.3em - 10px); }[data-page="features"] .mnb-hero-claim--lead2,
[data-page="features"] .mnb-hero-claim--payoff { margin-top: 0; }/* Slate, matching the header bar (#6E7C83) -- red read as alarm on a site that
   uses red medallions for "not accepted", and at 64px it dominated the payoff
   line beneath it. The slate ties the hero to the site's own chrome and lets
   line 2 carry the weight. 4.13:1 on the light background, which clears AA for
   large text. Dark mode keeps gold: slate on charcoal has almost no contrast. */
/* ============================================================================
   HERO BAND -- the white plate the two pitch lines sit on.
   Measured from Jordan's comp: page grey #E4E4E4, white band across the middle
   83% of the height, fading out horizontally by 15% from each edge, a 1px
   #C9C9C9 hairline on top and a soft shadow beneath peaking at #A2A2A2 and
   dying over ~9px.

   NOT a box-shadow. The shadow in the comp fades horizontally in step with the
   band (measured: full strength from 25% to 75%, gone by the edges), and a
   box-shadow runs the full width at even strength. Layered gradients are the
   only way to make the shadow disappear exactly where the plate does.

   Wraps BOTH lines, so it is a container rather than a per-line background --
   the plate must not break between them.
   ========================================================================== */
.mnb-hero-band {
  position: relative;
  padding: 1px 0;
  /* overflow-x: clip contains the sliding segments -- at 50vw they start well
     outside the frame and would otherwise widen the document and produce a
     horizontal scrollbar mid-animation. clip rather than hidden, and x only,
     so the drop shadow and the drips can still paint outside vertically. */
  overflow-x: clip;
  /* Clears the content below. The shadow is a ::after at top:100%, which is
     absolutely positioned and therefore takes NO layout space -- so without
     this the next section sits against the plate's edge with the shadow
     overlapping it. 25px = the shadow's own 10px plus 15px of breathing room. */
  margin-bottom: 25px;
  /* NO background and NO mask on this element. A mask clips an element's
     PSEUDO-ELEMENTS as well as its own box, so masking here erased ::after --
     which lives at top:100%, outside the box -- and the shadow disappeared
     entirely. Plate and shadow are therefore separate masked layers. */
}/* The plate. ::before precedes the two <p> children in document order, so it
   paints behind them without needing a z-index. */
.mnb-hero-band::before {
  content: "";
  position: absolute;
  inset: 0;
  /* Plate at 35% white rather than solid, so the page grain reads through it
     -- the band lifts the area instead of covering it. The 1px hairline stays
     solid; at this opacity it would vanish and the plate would lose its top
     edge. */
  background: linear-gradient(to bottom, #C9C9C9 0 1px, rgba(255,255,255,.35) 1px 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 15%, #000 85%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 15%, #000 85%, transparent 100%);
}/* The shadow, cast BELOW the plate onto the page. Deliberately not on white:
   it falls on the site's own grained background, so the grain reads through
   it. Its horizontal mask is tighter than the plate's (22/78 vs 15/85) so the
   shadow dies before the plate does, as in the comp. */
.mnb-hero-band::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 100%;
  height: 10px;
  background: linear-gradient(to bottom, rgba(0,0,0,.28), rgba(0,0,0,0));
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 22%, #000 78%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 22%, #000 78%, transparent 100%);
  pointer-events: none;
}[data-theme="dark"] .mnb-hero-band::before {
  background: linear-gradient(to bottom, rgba(255,255,255,.10) 0 1px, rgba(255,255,255,.045) 1px 100%);
}[data-theme="dark"] .mnb-hero-band::after { background: linear-gradient(to bottom, rgba(0,0,0,.45), rgba(0,0,0,0)); }[data-page="features"] .mnb-hero-claim--melt { color: #6E7C83; }/* THE STARS. Wrapped in a span because CSS cannot target a bare character.
   - Raised 0.1em: U+2605 is drawn centred on its own em box, which sits lower
     than the optical middle of Anton's caps, so it reads as dropped.
   - Colour uses --mnb-text, which already flips #171E22 / #FFFFFF across both
     dark paths -- one declaration, and it cannot drift from the theme.
   - Slightly smaller than the caps: at full size the star out-weighs the
     letters it separates.
   NOTE: the mirror reflection renders attr(data-text), which is plain text
   with no elements, so the reflected stars keep the line colour and sit at
   their natural height. At the reflection's opacity that is not visible; it
   cannot be fixed without abandoning the text-copy approach. */
/* MIRRORED LINE. Suppresses the shared text-copy reflection and uses a real
   duplicated span instead, so per-character styling (the stars) reflects
   correctly. Geometry matches the ::after it replaces. */
/* [data-page] prefix raises this to (0,2,1) so it beats the base
   .mnb-hero-claim::after at (0,1,1), which sits LATER in the file. Without the
   prefix the two tie, source order wins, and BOTH reflections render stacked --
   which reads as a wide smear rather than a mirror. */
.mnb-hero-claim--mirrored::after { content: none !important; }.mnb-hero-reflect {
  position: absolute;
  left: 0;
  top: calc(100% - .25em);
  width: 100%;
  transform: scaleY(-1);
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to top, rgba(0, 0, 0, 0.25), transparent 80%);
          mask-image: linear-gradient(to top, rgba(0, 0, 0, 0.25), transparent 80%);
}/* "10 seconds!" -- the payoff, in the link colour. var(--mnb-link) rather than
   a hardcoded #C8102E so it tracks the theme exactly as links do: the red in
   light, gold in dark. One declaration, and it cannot drift from the link
   colour if that is ever retuned. */
/* ============================================================================
   MELTING TEXT -- experiment on line 1 only.
   Recipe per the Prismic article: a semi-transparent duplicate and a blurred
   duplicate stacked behind the text, both stretched downward and faded by a
   `drip` keyframe, with the main text bobbing gently on `melt`.

   Built with real duplicate SPANS rather than ::before/::after with
   attr(data-text), for the same reason the reflection was: data-text is plain
   text, so the star spans would vanish from the drip layers and the drips
   would not match what is dripping.

   EASY TO REMOVE: delete the --melt class from the <p> and this block.
   ========================================================================== */
/* STAGGERED ENTRANCE on line 1. One 8s cycle: each segment fades in 0.5s after
   the one before, all three hold for ~5s, then they fade out in the same order
   and the cycle repeats. A single keyframe with per-segment delays does the
   whole thing -- three keyframe blocks would be the bloaty way.
   The delay offsets the entire cycle, so the exit cascades in the same order
   as the entrance, which reads as deliberate rather than as a glitch. */
.mnb-seg {
  opacity: 0;
  /* inline-block because transform does NOT apply to non-replaced inline
     elements -- as plain inline spans the translateX would be ignored and only
     the fade would run. */
  display: inline-block;
  animation: mnb-seg-cycle-r 12.8s ease-in-out infinite;
}/* "Scan" enters from the left, everything after it from the right, so the line
   assembles toward the middle rather than marching one way. */
.mnb-seg--1 { animation-name: mnb-seg-cycle-l; }/* Five beats now -- each star gets its own. Delays tightened from .5s to .3s
   so the sequence still completes in ~1.2s; at .5s across five segments the
   last word would not land until 2s, which drags. */
.mnb-seg--1 { animation-delay: 0s; }.mnb-seg--2 { animation-delay: .3s; }.mnb-seg--3 { animation-delay: .6s; }.mnb-seg--4 { animation-delay: .9s; }.mnb-seg--5 { animation-delay: 1.2s; }/* Two keyframes, one per direction. The slide happens only on the way IN; the
   exit fades in place and then resets the offset at 100% while opacity is
   already 0, so the loop restarts from the right position invisibly. */
@keyframes mnb-seg-cycle-l {
  /* 50vw: the segments start beyond the frame's left edge and fly to centre.
     vw rather than px so the travel scales with the viewport -- a fixed 500px
     would overshoot wildly on a phone. */
  0%   { opacity: 0; transform: translateX(-50vw); }
  5%   { opacity: 1; transform: translateX(0); }      /* ~0.64s slide + fade in */
  89%  { opacity: 1; transform: translateX(0); }      /* holds ~9.6s */
  97%  { opacity: 0; transform: translateX(0); }      /* ~1s fade out, in place */
  100% { opacity: 0; transform: translateX(-50vw); }  /* invisible reset */
}@keyframes mnb-seg-cycle-r {
  0%   { opacity: 0; transform: translateX(50vw); }
  5%   { opacity: 1; transform: translateX(0); }
  89%  { opacity: 1; transform: translateX(0); }
  97%  { opacity: 0; transform: translateX(0); }
  100% { opacity: 0; transform: translateX(50vw); }
}.mnb-hero-claim--melt { isolation: isolate; }.mnb-melt {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  pointer-events: none;
  z-index: -1;                    /* behind the crisp text */
  /* Option A: centre origin, so scaleY grows the layer up AND down rather
     than only downward. Note the upward half stays largely hidden behind the
     crisp text -- same colour, z-index -1 -- until it clears the cap height. */
  transform-origin: center;
}/* Drip layers in black rather than inheriting the slate. The slate is light
   enough that at the keyframe's 40% peak it barely separated from the plate;
   black gives the same 40% something to actually show. The static opacity
   values here are inert -- mnb-drip animates opacity, so the keyframe wins. */
/* 8s to match mnb-seg-cycle. On its old 3.2s loop the drip was independent of
   the segments, so it fired at arbitrary points -- including while the words
   were still sliding in, and sometimes while they were hidden entirely. Same
   duration means the two stay locked forever instead of drifting. */
/* opacity: 0 as the resting state, and animation-fill-mode: backwards.
   Layer B has a .35s animation-delay, and with the default fill-mode the
   element uses its OWN styles until the animation starts -- so a static
   opacity of .28 painted a black ghost over the words while they were still
   sliding in. `backwards` applies the 0% keyframe during the delay instead,
   and a resting opacity of 0 means neither layer can ever show outside the
   window mnb-drip defines. */
.mnb-melt--a { color: #000; opacity: 0;
  animation: mnb-drip 1.6s ease-out 1.8s infinite backwards,
             mnb-gate 12.8s step-end infinite; }/* Layer B is the 10px-blurred copy, and in black it read as a dark outer
   glow around the letters as the drip came up. Hidden rather than deleted:
   remove the display:none below to bring the soft halo back. */
.mnb-melt--b { display: none; color: #000; opacity: 0; filter: blur(10px);
  animation: mnb-drip 1.6s ease-out 2.0s infinite backwards,
             mnb-gate 12.8s step-end infinite; }.mnb-melt .mnb-star {
  /* Drip copies stay plain -- the clip/transparent-fill combo would paint them
     as the gold fill instead of the drip's own black. */
  color: inherit;
  background: none;
  -webkit-text-fill-color: currentColor;
  text-shadow: none;
  filter: none;      /* drips stay flat -- the glow belongs to the crisp glyphs */
}/* Dark theme: black on charcoal is invisible -- the drips take white there. */
/* Gold rather than white in dark mode. White ghosting out of the gold letters
   read as a colour shift -- two hues overlapping -- where gold-on-gold reads
   as a true glow. Mirrors the light theme, where the drip is black beneath
   slate letters. */
[data-theme="dark"] .mnb-melt--a,
[data-theme="dark"] .mnb-melt--b { color: var(--mnb-gold); }/* Timed against the segment cycle: nothing until 22% (1.8s -- the last word
   lands at 1.2s + 0.6s to fade in), one drip through the hold, finished by 80%
   where the segments start fading out. */
/* ONE-WAY PULSE: grow and fade, then repeat. The previous shape peaked at 50%
   and returned to scaleY(1) by 100% -- and because opacity came back up to .30
   on the way, that return was visible as a shrink. Now the growth runs the
   whole cycle and opacity is 0 at both ends, so the reset from 1.35 back to 1
   happens at the loop boundary while nothing is on screen.
   Duration is 1.6s (set on .mnb-melt--a). */
@keyframes mnb-drip {
  0%   { transform: scaleY(1);    opacity: 0;   }   /* invisible start */
  12%  { transform: scaleY(1.05); opacity: .20; }   /* fades up as it begins */
  100% { transform: scaleY(1.75); opacity: 0;   }   /* grows out and vanishes */
}/* The window the drip may show in. TWO tracks are needed because opacity is
   already driven by mnb-drip and two animations cannot share a property --
   so the gate uses `visibility`, with step-end so it snaps rather than fades.
   12.8s is exactly 8 x 1.6s, keeping pulse and gate phase-locked forever. */
@keyframes mnb-gate {
  0%   { visibility: hidden; }
  14%  { visibility: visible; }   /* 1.8s -- the last word has landed */
  97%  { visibility: hidden; }    /* 12.4s -- the drip keeps pulsing through
                                     the 1s fade-out and stops once the words
                                     are gone. It reopens at 14% of the next
                                     cycle, i.e. only after the slide-ins have
                                     finished. */
  100% { visibility: hidden; }
}/* Bounce distance 0 -- the solid front text now holds still. Kept as a live
   keyframe rather than deleted so the travel is one number away: change the
   0px below back to 3px (or higher) to bring the bob back.
   Note this animates the whole <p>, so it moved the drip layers with it; the
   drips have their own scaleY and are unaffected by this being 0. */
@keyframes mnb-melt-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(0px); }
}.mnb-hero-claim--melt { animation: mnb-melt-bob 1.6s ease-in-out infinite;   /* 8 per 12.8s cycle -- phase-locked */ }/* THREE-LINE HERO. Line 2 is now two lines, so the sibling selectors that used
   to mean "line 2" need explicit classes -- .mnb-hero-claim + .mnb-hero-claim
   would otherwise match both of the new lines and the third would inherit
   whatever the second set. */
[data-page="features"] .mnb-hero-claim--lead2 {
  color: #525252;
  letter-spacing: 0;
  font-size: 3.3rem;          /* +20% on the old 2.75rem */
}[data-theme="dark"] [data-page="features"] .mnb-hero-claim--lead2 { color: var(--mnb-text); }/* The payoff line carries only the accent, so its own colour never shows. */
[data-page="features"] .mnb-hero-claim--payoff { letter-spacing: 0; }/* Seams: tight between 1 and 2a, tighter still between 2a and its payoff --
   they are one sentence broken across two lines, not two statements. */
/* Room for line 2's own reflection to land before line 3 starts. At -14px the
   seam was ~2px, which was fine while this line had no mirror; with one, the
   flipped copy would paint straight over the payoff. -6px gives ~10px, the
   same seam that worked when lines 1 and 2 both reflected. */
[data-page="features"] .mnb-hero-claim--lead2 { margin-top: 0; margin-bottom: calc(.3em - 6px); }.mnb-hero-claim--payoff { margin-top: 0; }/* 5px clear of the line above. padding, not margin: this line's margin-top is
   pinned to 0 by the seam rule, and adjacent vertical margins collapse anyway.
   Declared BEFORE the media query below so the mobile value can override it --
   placed after, it would win at every width and silently ignore the mobile
   rule. */
[data-page="features"] .mnb-hero-claim--payoff { padding-top: 5px; }/* Just the number heavier. NOTE: Feross ships a single 400 weight (see the
   @font-face in includes/header.php), so 700 here is SYNTHETIC bold -- the
   browser thickens the strokes algorithmically rather than swapping to a
   drawn bold. On a brush face that can smear; if it does, the alternatives
   are a size bump on this span instead, or leaving the number at 400. */
/* ============================================================================
   ONE-SHOT INTRO for lines 2 and 3. Both start invisible; line 2 types itself
   out, then line 3 fades in. `forwards` on both, and no `infinite` -- this
   plays once per page load and then stays put.

   The typewriter is a clip-path reveal, not the usual width animation. Width
   would need the text's own measure: an inline-block's 100% resolves against
   the <p>, which is full-bleed and centred, so the reveal would run far past
   the end of the words. clip-path inset() clips the element's own box, so it
   is correct at any size and survives the responsive font changes.

   steps(33) is one step per character of "Complete a full entry in under..." --
   that is what makes it read as typing rather than a wipe.
   ========================================================================== */
[data-page="features"] .mnb-type {
  display: inline-block;
  clip-path: inset(0 100% 0 0);
  animation: mnb-type 1.6s steps(33, end) .4s forwards;
}@keyframes mnb-type { to { clip-path: inset(0 0 0 0); } }/* Typing ends at 2.0s (.4s delay + 1.6s). A .25s beat, then a 2.8s fade --
   slow enough to read as the line settling in rather than switching on. */
[data-page="features"] .mnb-hero-claim--payoff {
  opacity: 0;
  animation: mnb-payoff-in 2.8s ease-out 2.25s forwards;
}@keyframes mnb-payoff-in { to { opacity: 1; } }[data-page="features"] .mnb-hero-num { font-weight: 500; }[data-page="features"] .mnb-hero-accent {
  /* Amber, matching the stars. Same contrast caveat as there. */
  color: var(--mnb-gold);
  /* INNER SHADOW, 0 offset: dark hugging the inside of the edge, clean gold
     through the middle. The shadow is #B8860B -- considerably darker than the
     first pass, which is what "a little darker" meant; the middle stays full
     brand gold rather than being dragged down with it.

     Matched to the Photoshop panel: Inner Glow, Normal, black at 26% opacity,
     Softer, Source Edge, Size 5px. 26% black over #FFCC00 computes to #BD9700,
     which is the edge stop; 5px on 58px of cap height is ~9%, which is the
     falloff.

     CAVEAT: a linear-gradient runs top-to-bottom only, so this darkens the
     horizontal edges of each glyph and not the vertical ones. A true all-round
     inner shadow is not expressible on text in CSS -- text-shadow has no inset
     keyword, and -webkit-text-stroke straddles the outline rather than sitting
     inside it. On condensed caps like Anton the horizontal edges are most of
     what reads, so this carries the effect.
     Done as a GRADIENT clipped to the glyph, not a text-shadow. The earlier
     text-shadow version darkened the MIDDLE and left the edges bright, because
     a shadow is a blurred copy of the glyph painted over the fill -- densest
     at the centre. A gradient puts the dark exactly where the comp has it. */
  /* Flat gold plus the SVG inner-glow filter defined in features.php. The
     gradient approach is gone: a linear-gradient runs on one axis only, so it
     could darken the top and bottom of a glyph but never the left and right.
     The filter wraps the whole letterform, which is what the Photoshop panel
     does. Note the glow's 5px is in CSS pixels and does NOT scale with
     font-size, so it reads slightly heavier on the smaller mobile type. */
  filter: url(#mnb-inner-glow);
  /* EXPERIMENT: Feross on the payoff words only, Anton on the rest of the
     line. text-transform: none because a script face set in all-caps breaks
     the connecting letterforms it is drawn for; letter-spacing back to 0 for
     the same reason -- the .04em on this line is tuned to Anton. Feross reads
     smaller than Anton at the same size (lower x-height relative to caps), so
     it is bumped to compensate. */
  /* Anton, same as the rest of the line. The Feross-specific compensations go
     with it: the 1.25em bump existed because a script face reads smaller at a
     matched size, and letter-spacing: 0 because script does not want tracking.
     At the same face as its neighbours neither applies. */
  font-family: var(--mnb-font-impact);
  text-transform: uppercase;
}.mnb-star {
  /* Amber in light; white in dark, set below. NOTE this measures ~1.7:1 on the
     light plate, well under the 3:1 AA minimum for large text -- it reads as a
     highlight rather than as legible copy, which is fine while the words it
     marks are decorative but worth knowing. */
  color: var(--mnb-gold);
  /* INNER SHADOW, 0 offset: dark hugging the inside of the edge, clean gold
     through the middle. The shadow is #B8860B -- considerably darker than the
     first pass, which is what "a little darker" meant; the middle stays full
     brand gold rather than being dragged down with it.

     Matched to the Photoshop panel: Inner Glow, Normal, black at 26% opacity,
     Softer, Source Edge, Size 5px. 26% black over #FFCC00 computes to #BD9700,
     which is the edge stop; 5px on 58px of cap height is ~9%, which is the
     falloff.

     CAVEAT: a linear-gradient runs top-to-bottom only, so this darkens the
     horizontal edges of each glyph and not the vertical ones. A true all-round
     inner shadow is not expressible on text in CSS -- text-shadow has no inset
     keyword, and -webkit-text-stroke straddles the outline rather than sitting
     inside it. On condensed caps like Anton the horizontal edges are most of
     what reads, so this carries the effect.
     Done as a GRADIENT clipped to the glyph, not a text-shadow. The earlier
     text-shadow version darkened the MIDDLE and left the edges bright, because
     a shadow is a blurred copy of the glyph painted over the fill -- densest
     at the centre. A gradient puts the dark exactly where the comp has it. */
  /* Flat gold plus the SVG inner-glow filter defined in features.php. The
     gradient approach is gone: a linear-gradient runs on one axis only, so it
     could darken the top and bottom of a glyph but never the left and right.
     The filter wraps the whole letterform, which is what the Photoshop panel
     does. Note the glow's 5px is in CSS pixels and does NOT scale with
     font-size, so it reads slightly heavier on the smaller mobile type. */
  filter: url(#mnb-inner-glow);
  /* Raised with vertical-align, NOT position/top. A positional offset is laid
     out first and then scaled by the parent's scaleY, and because the star is
     smaller (.82em) and sits higher than the caps, it travels a different
     distance from the transform's centre line -- so it drifts against the
     letters as the drip layer stretches. vertical-align shifts the baseline
     itself, which scales with the line box, so the star grows in step. */
  vertical-align: .1625em;
  font-size: .82em;
}[data-theme="dark"] .mnb-star { color: #fff; }/* Feross on the FIRST line only (Jordan 2026-08-05). :has() picks the first of
   the pair, so the second keeps Anton and the "Coming soon" claims on download
   and login are untouched.
   text-transform is dropped here: Feross is a script face, and script set in
   all-caps breaks the connecting letterforms it is drawn for. "Scan, sign,
   done." is three short words, which is the shape a script face handles best. */
[data-page="features"] .mnb-hero-claim--melt {
  /* Back to Anton. letter-spacing returns to the base .01em -- the 0 was for
     the script face, which does not want tracking. */
  font-family: var(--mnb-font-impact);
  text-transform: uppercase;
  /* Much larger than line 2 (4rem vs 2.75rem) because a script face carries a
     lower x-height relative to its caps -- at matched font-sizes Feross reads
     as the subordinate line, which is backwards when it is the hook. */
  font-size: 4rem;
}/* Line 1's reflection up 2px. The shared .1875em is tuned to Anton's baseline
   at 44px; this line runs at 64px, where the same ratio leaves a slightly
   wider gap. .25em is +4px at 64px and +2px at the 32px mobile size, so it
   does not overcorrect on a phone. */
[data-page="features"] .mnb-hero-claim--melt::after {
  top: calc(100% - .25em);
}/* SECOND line only: charcoal in light, white in dark. One declaration covers
   all three theme paths because --mnb-text already flips (#171E22 / #FFFFFF)
   under [data-theme="dark"] AND under prefers-color-scheme -- so no dark
   override is needed here, and none can drift out of step later.
   The adjacent-sibling selector is what makes it the second line: the first
   keeps the red set above. */
[data-page="features"] .mnb-hero-claim--payoff {
  font-size: 5rem;   /* desktop. NOT on .mnb-hero-claim -- that base sizes all
                        three hero lines. */
  color: #525252;   /* this line only -- not the site-wide --mnb-text token */
  /* Anton is condensed, so its default fit is tight by design; a little
     tracking opens the longer line without fighting the face. em-based, so
     mobile gets proportionally the same air rather than looking loose at
     20px. Line 1 stays at the base .01em. */
  letter-spacing: 0;
}/* Line 2's reflection up ~2px. .1875em -> .23em is +2.4px at the 44px desktop
   size and +1.1px at 22px mobile -- em-based so the nudge scales with the type
   rather than looking twice as large on a phone. */
[data-page="features"] .mnb-hero-claim--payoff::after {
  top: calc(100% - .23em);
}[data-theme="dark"] [data-page="features"] .mnb-hero-claim--melt { color: var(--mnb-gold); }/* Re-stated for the dark paths at higher specificity. Without these the gold
   rule above -- same (0,3,0) weight but later in the file -- would win on the
   second line too and both lines would be gold in dark mode. Being explicit
   means source order cannot decide this later. */
[data-theme="dark"] [data-page="features"] .mnb-hero-claim--payoff { color: var(--mnb-text); }/* Hero claim -- the features page's one-line pitch, under the breadcrumb.
   Deliberately a <p>, not a second <h1>: the page already has one ("App
   Features"), and a document with two h1s is ambiguous to screen readers and
   to search engines about what the page is actually about. This is styled to
   read as a headline while staying a paragraph in the outline. */
.mnb-hero-claim {
  /* Sized and reflected to match .mnb-page-title -- it is the page's second
     headline in everything but document outline. margin-bottom leaves room for
     the flipped copy, which is painted outside the box by ::after and would
     otherwise collide with the first feature card. */
  margin: 44px 0 66px;   /* was 24 / 46 -- +20px breathing room top and bottom */
  text-align: center;
  font-family: var(--mnb-font-impact);
  font-size: 2.75rem;
  line-height: 1.06;      /* was 1 -- single-line only; two lines need the gap */
  font-weight: 400;
  letter-spacing: .01em;
  text-transform: uppercase;
  color: #525252;
  position: relative;
}/* Same mirror trick as the page title: a real flipped copy via data-text
   (set in footer.php), masked to fade out. -webkit-box-reflect is unreliable
   on iOS Safari, which is why this is done the long way. */
.mnb-hero-claim::after {
  content: attr(data-text);
  position: absolute;
  left: 0;
  top: calc(100% - 0.1875em);
  width: 100%;
  transform: scaleY(-1);
  pointer-events: none;
  /* Mask peak 0.15 -> 0.25 (Jordan 2026-08-05): +10 points, so the reflection
     is noticeably present rather than a hint. Applies to both themes -- the
     mask is alpha, not colour, so it strengthens the gold ghost in dark and
     the slate one in light equally. The page-title reflections still use 0.15;
     say the word if those should follow. */
  -webkit-mask-image: linear-gradient(to top, rgba(0, 0, 0, 0.25), transparent 80%);
          mask-image: linear-gradient(to top, rgba(0, 0, 0, 0.25), transparent 80%);
}/* Pricing hero: reflection up 2px. Scoped to this page rather than nudging the
   shared rule above, which also serves the "Coming soon" lines on download and
   login. .1875em is 8.25px at the 2.75rem base, so .2325em is +2px there and
   scales proportionally on mobile. */
/* The pricing hero now carries a real duplicate span, so the shared ::after
   nudge that used to live here no longer applies. */
[data-page="pricing"] .mnb-hero-reflect { top: calc(100% - .2325em); }[data-theme="dark"] .mnb-hero-claim { color: #fff; }/* THE ANNUAL OFFER, on its own line under the toggle. As a block it centres
   itself and needs none of the vertical-align and lopsided-padding correction
   the inline version required -- that whole problem came from trying to sit a
   Feross pill on an Anton baseline. */
.mnb-pricing__offer {
  display: block;
  width: max-content;
  max-width: 100%;
  margin: -14px auto 26px;
  cursor: pointer;
  /* Anton. The Feross-specific compensations go with it: tracking returns to
     the site default, and the padding is even again -- the top-heavy value
     existed only because a script face sits high in its line box. */
  font-family: var(--mnb-font-impact);
  font-size: .95rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  line-height: 1;
  /* Swapped: the flag red at rest, the header bar's slate on hover. Red is the
     louder of the two, which suits an invitation that has to be noticed; the
     slate on hover reads as the button settling rather than lighting up. */
  color: #fff;
  background: #C8102E;
  padding: .9em 1.1em .9em;
  border-radius: 5px;
  transition: background var(--mnb-ease);
}/* Hover swaps the BACKGROUND only -- text stays white in light, black in dark.
   A brightness filter was doing it before, which lightened the type along with
   the fill and washed the whole pill out. */
.mnb-pricing__offer:hover { background: #6E7C83; }
[data-theme="dark"] .mnb-pricing__offer:hover { background: #fff; }.mnb-pricing__offer-star { font-size: .85em; vertical-align: .06em; margin: 0 .15em; }/* Once annual is selected the invitation is spent, so it goes away rather than
   sitting there telling you to do what you have already done. */
.mnb-cycle--yr:checked ~ .mnb-pricing__offer { display: none; }[data-theme="dark"] .mnb-pricing__offer { background: var(--mnb-gold); color: #000; }
@media (max-width: 600px) {
/* Half the reduction on mobile: 20px off a 32px line is proportionally twice
     what it is off a 64px one, and would pull line 2 into line 1's descenders. */
  [data-page="features"] .mnb-hero-claim--melt { margin-bottom: calc(.3em - 0px); }
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) .mnb-hero-band::before {
    background: linear-gradient(to bottom, rgba(255,255,255,.10) 0 1px, rgba(255,255,255,.045) 1px 100%);
  }:root:not([data-theme]) .mnb-hero-band::after { background: linear-gradient(to bottom, rgba(0,0,0,.45), rgba(0,0,0,0)); }
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) .mnb-melt--a,
  :root:not([data-theme]) .mnb-melt--b { color: var(--mnb-gold); }
}
@media (prefers-reduced-motion: reduce) {
.mnb-hero-claim--melt,
  .mnb-melt,
  .mnb-seg { animation: none; }.mnb-melt { opacity: 0; }.mnb-seg  { opacity: 1; }
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) [data-page="features"] .mnb-hero-claim--lead2 { color: var(--mnb-text); }
}
@media (max-width: 600px) {
[data-page="features"] .mnb-hero-claim--lead2 { font-size: 1.50rem; }[data-page="features"] .mnb-hero-claim--lead2 { margin-bottom: calc(.3em - 1px); }/* 5px clear of the line above, mobile only. padding rather than margin: the
     payoff's margin-top is pinned to 0 by the seam rule, and adjacent vertical
     margins collapse -- padding does neither. */
  [data-page="features"] .mnb-hero-claim--payoff { padding-top: 5px; }
}
@media (prefers-reduced-motion: reduce) {
[data-page="features"] .mnb-type { clip-path: none; animation: none; }[data-page="features"] .mnb-hero-claim--payoff { opacity: 1; animation: none; }
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) .mnb-star { color: #fff; }
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) [data-page="features"] .mnb-hero-claim--melt { color: var(--mnb-gold); }:root:not([data-theme]) [data-page="features"] .mnb-hero-claim--payoff { color: var(--mnb-text); }
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) .mnb-hero-claim { color: #fff; }
}
@media (max-width: 768px) {
.mnb-hero-claim { font-size: 2.75rem; }
}
@media (max-width: 600px) {
.mnb-hero-claim { font-size: 1.4rem; margin: 34px 0 48px; }
}
@media (max-width: 600px) {
[data-page="features"] .mnb-hero-claim--melt { font-size: 1.6rem; }/* Line 2 down ~10% on mobile (1.4 -> 1.25rem). Scoped to the features page
     rather than changed on the base rule, because .mnb-hero-claim also carries
     the "Coming soon" lines on download and login, which should not shrink. */
  [data-page="features"] .mnb-hero-claim--payoff { font-size: 1.75rem; }/* 15px clear of the content above and below on mobile -- OUTSIDE the plate,
     so the white does not grow. Bottom is 25px because the shadow is a ::after
     at top:100% and takes no layout space: 10px of shadow plus the 15px gap. */
  .mnb-hero-band { margin-top: 40px; margin-bottom: 50px; }
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) .mnb-pricing__offer { background: var(--mnb-gold); color: #000; }
  :root:not([data-theme]) .mnb-pricing__offer:hover { background: #fff; }
}