/* =====================================================================
   Sojourn Logbook — marketing site
   ---------------------------------------------------------------------
   Tokens and section rhythm come from C:\Claude\Sojourn\marketing\SITE_STYLE.md,
   the shared system across sojourn.tax, sojourn-group.com and this site. Keep
   them identical — the navy trio in particular is the same on every Sojourn
   site and must not drift.

   CACHE-BUST: every page links this as style.css?v=YYYYMMDDx. Bump the version
   on EVERY change here or warm-cache visitors keep the old file. This has bitten
   the tax site before (see the marketing-site-css-cache-bust memory).
   ===================================================================== */

:root {
  /* Core navy — the brand ground. Identical on every Sojourn site. */
  --navy:            #042C53;
  --navy-highlight:  #0A3868;   /* lighter navy, only inside the hero gradient */
  --navy-dark:       #03152B;   /* the DARKER navy — accent bands + footer     */

  --white:           #FFFFFF;
  --cream:           #F1EFE8;

  --lightblue-100:   #B5D4F4;   /* body text on navy      */
  --lightblue-200:   #85B7EB;   /* secondary / italic     */
  --mid-grey:        #5A7A9E;   /* eyebrows, captions     */

  /* Logbook's accent. 6.24:1 on --navy (passes AA).
     Deep violet #6D28D9 scored 1.98:1 and is DEAD — do not reinstate it or any
     similarly dark hue. The descriptor sits ON midnight, so the accent must be
     a light tint. Settled by Pierre, 2026-07-18. ONE accent value only — the
     arc in the lockup only reads lighter because it is a thin anti-aliased
     curve, not because it carries a second colour. */
  --accent:          #38B6FF;
  /* Recommendation badge ONLY. Deliberately not a second brand accent — the
     brand is midnight + #38B6FF, and this green must not spread beyond the
     "Best value" pill. navy-dark on it = 10.52:1. */
  --good:            #4ADE80;
  --accent-deep:     #0E6BA8;   /* accent darkened for text ON light grounds   */

  /* Sibling product accents — used ONLY on the Tax bundle page, and never lit
     at the same time as --accent in one viewport (four bright accents on one
     dark screen reads as a toy). */
  --tax-ink:         #FF5F50;   /* lightened tax red, 4.72:1 — the logo red
                                   #E30F01 is 2.91:1 and fails on navy        */

  --font-serif: "Tinos", Georgia, "Times New Roman", serif;
  --font-sans:  "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --measure: 1180px;
  --hairline: 1px solid rgba(255, 255, 255, 0.14);
}

/* ---------- reset ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  background: var(--navy);
  color: var(--lightblue-100);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; }
img { height: auto; }

h1, h2, h3, h4 {
  font-family: var(--font-serif);
  color: var(--white);
  font-weight: 700;
  line-height: 1.18;
  margin: 0 0 .5em;
  letter-spacing: -0.01em;
}

h1 { font-size: clamp(2.15rem, 5.2vw, 3.6rem); }
h2 { font-size: clamp(1.7rem, 3.4vw, 2.5rem); }
h3 { font-size: clamp(1.16rem, 2vw, 1.42rem); }

p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--white); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--accent); color: var(--navy-dark);
  padding: 12px 20px; font-weight: 600; border-radius: 0 0 8px 0;
}
.skip-link:focus { left: 0; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- layout ---------- */

.wrap { width: 100%; max-width: var(--measure); margin: 0 auto; padding: 0 24px; }
.wrap--narrow { max-width: 820px; }

/* The navy / navy-dark MIX. A page reads dark -> navy -> dark -> navy -> dark,
   never one flat tone. This is the single most-corrected detail in the shared
   system, so the rhythm lives in these classes rather than being hand-applied. */
.band            { padding: clamp(64px, 8.5vw, 108px) 0; background: var(--navy); }
.band--dark      { background: var(--navy-dark); border-top: var(--hairline); border-bottom: var(--hairline); }
.band--cream     { background: var(--cream); color: #33413C; }
.band--cream h1,
.band--cream h2,
.band--cream h3  { color: var(--navy); }
.band--cream a   { color: var(--accent-deep); }
.band--tight     { padding: clamp(44px, 5vw, 68px) 0; }

/* ---------- masthead ---------- */

.masthead {
  position: sticky; top: 0; z-index: 100;
  background: rgba(3, 21, 43, 0.88);
  backdrop-filter: saturate(160%) blur(12px);
  border-bottom: var(--hairline);
}
.masthead__inner {
  display: flex; align-items: center; gap: 20px;
  min-height: 70px;
}

/* Size the lockup by HEIGHT, never width.
   assets/logo-logbook.svg was exported on a square 810x810 canvas with the
   artwork occupying only the middle 424x175 — 78% of its height was empty. The
   file's viewBox is now cropped to the artwork (aspect ~2.36:1, matching the tax
   site's 78x34 mark), but sizing by height keeps the bar's height explicit and
   immune to any future re-export. */
.masthead__logo { display: inline-flex; align-items: center; flex: none; }
.masthead__logo img { height: 40px; width: auto; display: block; }

.masthead__nav {
  margin-left: auto;
  display: flex; align-items: center; gap: 24px;
  font-size: 14px;
}
.masthead__nav a { color: var(--lightblue-100); text-decoration: none; white-space: nowrap; }
.masthead__nav a:hover,
.masthead__nav a[aria-current="page"] { color: var(--white); }
.masthead__nav a[aria-current="page"] { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; }

/* CTA pill — the masthead counterpart to the tax site's "Get Sojourn →".
   Navy-dark on accent is 8.12:1. */
.btn-pill {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 9px 20px; border-radius: 999px;
  background: var(--accent); color: var(--navy-dark) !important;
  font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap;
  transition: background .2s ease;
}
.btn-pill:hover { background: var(--white); color: var(--navy-dark) !important; }
.masthead__cta { flex: none; }

/* Hamburger. Hidden on desktop; the three bars morph into a cross when open. */
.nav-toggle {
  display: none;
  margin-left: auto;
  width: 42px; height: 42px; padding: 0;
  background: transparent; cursor: pointer;
  border: 1px solid rgba(255,255,255,.2); border-radius: 9px;
  flex-direction: column; align-items: center; justify-content: center; gap: 5px;
}
.nav-toggle span {
  display: block; width: 18px; height: 2px; border-radius: 2px;
  background: var(--lightblue-100);
  transition: transform .22s ease, opacity .18s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* The CTA appears twice in the markup: once inside <nav> for the mobile drawer,
   once outside it for the desktop bar. Exactly one is ever visible. */
.masthead__nav .nav-cta { display: none; }

@media (max-width: 900px) {
  .nav-toggle { display: flex; }
  .masthead__cta { display: none; }
  .masthead__nav .nav-cta { display: inline-flex; align-self: flex-start; margin-top: 6px; }

  /* Drawer. Collapsed by max-height rather than display:none so it animates and
     stays in the accessibility tree only when open (hidden via [hidden]). */
  .masthead__nav {
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 4px;
    margin: 0; padding: 14px 24px 22px;
    background: var(--navy-dark);
    border-bottom: var(--hairline);
    font-size: 16px;
  }
  .masthead__nav[hidden] { display: none; }
  .masthead__nav a { padding: 11px 0; }
  .masthead { position: sticky; }
}

/* ---------- hero ---------- */

.hero {
  background: linear-gradient(135deg, var(--navy-highlight) 0%, var(--navy) 60%, var(--navy-dark) 100%);
  padding: clamp(64px, 9vw, 128px) 0 clamp(56px, 7vw, 100px);
}
.hero__lede {
  font-size: clamp(1.06rem, 1.9vw, 1.28rem);
  color: var(--lightblue-100);
  max-width: 43ch;
}
.hero--page { padding: clamp(56px, 7vw, 92px) 0 clamp(44px, 5vw, 68px); }

/* Hero proof line. Sits between the lede and the waitlist form: verification in
   the hero where the settled positioning says it belongs, plus the CV claim. */
.hero__proof {
  margin-top: 18px;
  max-width: 46ch;
  font-size: clamp(0.95rem, 1.5vw, 1.05rem);
  color: var(--accent);
}


.eyebrow {
  font-family: var(--font-sans);
  font-size: 12px; font-weight: 600;
  letter-spacing: 2px; text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 16px;
}
.eyebrow--quiet { color: var(--mid-grey); }

.caption { font-size: 13.5px; color: var(--mid-grey); }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 14px 26px;
  font-family: var(--font-sans); font-size: 15.5px; font-weight: 600;
  border-radius: 10px; border: 1px solid transparent;
  text-decoration: none; cursor: pointer;
  transition: background .2s ease, color .2s ease, border-color .2s ease;
}
/* Navy text on the accent — 6.24:1, the same pair as accent-on-navy. */
.btn--primary { background: var(--accent); color: var(--navy-dark); }
.btn--primary:hover { background: var(--white); color: var(--navy-dark); }
.btn--ghost { border-color: rgba(255,255,255,.28); color: var(--white); background: transparent; }
.btn--ghost:hover { border-color: rgba(255,255,255,.6); background: rgba(255,255,255,.05); color: var(--white); }

.btn-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

/* ---------- waitlist form ---------- */

.waitlist { max-width: 520px; }
.waitlist__row { display: flex; gap: 10px; flex-wrap: wrap; }
.waitlist input[type="email"] {
  flex: 1 1 260px; min-width: 0;
  padding: 14px 16px;
  font-family: var(--font-sans); font-size: 15.5px;
  color: var(--white);
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.24);
  border-radius: 10px;
}
.waitlist input[type="email"]::placeholder { color: #7E9CBE; }
.waitlist input[type="email"]:focus { border-color: var(--accent); background: rgba(255,255,255,.1); }
/* Crew-role capture. Optional on purpose — it measures cabin-crew demand before
   we build for it (GTM §7) without adding a required field to the primary CTA. */
.waitlist__role {
  margin-top: 10px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 13.5px; color: var(--mid-grey);
}
.waitlist__role select {
  font-family: var(--font-sans); font-size: 14px;
  color: var(--white);
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.24);
  border-radius: 8px; padding: 8px 12px;
}
.waitlist__role select option { color: #0b1c30; background: #fff; }
.waitlist__role select:focus { border-color: var(--accent); }

.waitlist__note { font-size: 13px; color: var(--mid-grey); margin: 12px 0 0; }
.waitlist__msg { font-size: 14.5px; margin: 12px 0 0; min-height: 1.3em; }
.waitlist__msg[data-state="ok"] { color: var(--accent); }
.waitlist__msg[data-state="err"] { color: var(--tax-ink); }

/* ---------- cards & grids ---------- */

.grid { display: grid; gap: 22px; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }

.card {
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 14px;
  padding: 26px 24px;
}
.card h3 { margin-bottom: .4em; }
.card p:last-child { margin-bottom: 0; }
.card__num {
  font-family: var(--font-serif); font-size: 2rem; color: var(--accent);
  line-height: 1; display: block; margin-bottom: 10px;
}

/* ---------- tables ---------- */

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table.data {
  width: 100%; border-collapse: collapse;
  font-size: 14.5px; text-align: left;
  min-width: 640px;
}
table.data caption {
  text-align: left; font-size: 13.5px; color: var(--mid-grey);
  padding-bottom: 14px;
}
table.data th, table.data td {
  padding: 13px 14px;
  border-bottom: 1px solid rgba(255,255,255,.11);
  vertical-align: top;
}
table.data thead th {
  font-size: 11.5px; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--mid-grey); font-weight: 600;
  border-bottom-color: rgba(255,255,255,.26);
  white-space: nowrap;
}
table.data tbody th { color: var(--white); font-weight: 600; white-space: nowrap; }
.band--cream table.data th,
.band--cream table.data td { border-bottom-color: rgba(4,44,83,.14); }
.band--cream table.data thead th { color: #5E6B78; border-bottom-color: rgba(4,44,83,.3); }
.band--cream table.data tbody th { color: var(--navy); }

/* Status pills for the authority table. Deliberately NOT four bright colours —
   the accent marks shipping-at-launch, everything else is quiet grey, so the
   table reads as a roadmap rather than a Christmas tree. */
.pill {
  display: inline-block; white-space: nowrap;
  font-size: 11.5px; font-weight: 600; letter-spacing: .7px; text-transform: uppercase;
  padding: 4px 10px; border-radius: 999px;
  border: 1px solid currentColor;
}
.pill--launch { color: var(--accent); }
.pill--next   { color: var(--lightblue-200); }
.pill--later  { color: var(--mid-grey); }

/* Verification state. The PROCESS is the differentiator, not the count — so the
   accent marks "verified against primary legislation", and everything still being
   checked stays visibly on the page rather than being hidden. Hiding the
   in-progress ones would break the very claim the page is making. */
.pill--verified { color: var(--accent); }
.pill--partial  { color: var(--lightblue-200); }
.pill--checking { color: var(--mid-grey); }

/* ---------- concept-render framing ----------
   Every app visual on this site is a CONCEPT RENDER. Sojourn Logbook does not
   exist yet. This frame + its caption are the honesty mechanism carried over
   from the group hub — do not strip the "Concept" caption or the
   "In development" tag from any section that uses one. Presenting a mockup as a
   live screenshot would be a false claim about a product we have not built. */
.concept { margin: 0; }
.concept__frame {
  background: var(--navy-dark);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 18px;
  padding: 20px;
}
.concept figcaption {
  margin-top: 12px;
  font-size: 12.5px; color: var(--mid-grey);
  display: flex; align-items: center; gap: 8px;
}
.concept figcaption::before {
  content: "Concept";
  font-size: 10.5px; font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase;
  color: var(--navy-dark); background: var(--lightblue-200);
  padding: 3px 8px; border-radius: 4px; flex: none;
}

.tag-dev {
  display: inline-block; margin-left: 12px; vertical-align: middle;
  font-size: 11px; font-weight: 600; letter-spacing: 1.3px; text-transform: uppercase;
  color: var(--lightblue-200);
  border: 1px solid currentColor; border-radius: 999px;
  padding: 4px 11px;
}

/* ---------- pricing ---------- */

.price-grid { display: grid; gap: 22px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr)); align-items: start; }
.price {
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.13);
  border-radius: 16px; padding: 30px 26px;
  display: flex; flex-direction: column; height: 100%;
  /* Anchors the corner badge. "Best value" used to sit IN the flow and push the
     featured card's title and price down, so the three prices never sat on one
     line. Taking it out of flow aligns them. */
  position: relative;
}
.price--featured { border-color: var(--accent); border-width: 2px; }
/* Upper-right corner, out of flow. Green rather than the brand blue so it reads
   as a recommendation instead of more chrome, and cannot be mistaken for a
   second brand accent. #4ADE80 carries navy-dark text at 10.52:1 and sits at
   8.09:1 against the card; both pairs are enforced in check-site.py. */
.price__badge {
  position: absolute; top: 14px; right: 14px;
  font-size: 11px; font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase;
  color: var(--navy-dark); background: var(--good);
  padding: 4px 11px; border-radius: 999px;
}
/* Stops a long tier name running under the badge. */
.price--featured h3 { padding-right: 92px; }
.price__amount { font-family: var(--font-serif); font-size: 2.5rem; color: var(--white); line-height: 1; margin: 6px 0 4px; }
.price__per { font-size: 14px; color: var(--mid-grey); }
.price ul { list-style: none; padding: 0; margin: 20px 0 0; font-size: 15px; }
.price li { padding-left: 26px; position: relative; margin-bottom: 11px; }
.price li::before {
  content: ""; position: absolute; left: 2px; top: .55em;
  width: 9px; height: 9px; border-radius: 50%;
  border: 2px solid var(--accent);
}

/* ---------- per-authority pages ---------- */

/* A rule and the clause it came from, together. The citation is the whole point
   of these pages: an answer engine paraphrases an unsourced claim but cites a
   sourced one. Never render a rule here without its clause. */
.rule {
  padding: 20px 0;
  border-bottom: 1px solid rgba(255,255,255,.11);
}
.rule:first-of-type { border-top: 1px solid rgba(255,255,255,.11); }
.rule h3 { margin-bottom: .35em; }
.rule p { margin: 0; max-width: 72ch; }
/* An authority we have NOT verified still gets a page — but every rule on it
   carries the tag, so the status is visible at the rule, not just in a callout
   at the top the reader may have scrolled past. #85B7EB = 6.69:1 on navy. */
/* Authority tile: name/country left, flag right. Flags are SVG via <use> from
   an inlined sprite — NEVER emoji. Flag emoji have no glyph on Windows or
   Android and degrade silently to the bare letters ("NL"), which is exactly the
   bug the app hit with react-native flags. See CLAUDE.md, iconography rule. */
.authcard {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
.authcard__txt { min-width: 0; }
.flag {
  width: 30px;
  height: 20px;
  flex: none;
  border-radius: 2px;
  /* A hairline ring, not decoration: Canada, Singapore and Qatar are mostly
     white and would otherwise bleed into the navy card with no edge. */
  box-shadow: 0 0 0 1px rgba(255,255,255,.22);
}
@media (max-width: 420px) { .flag { width: 26px; height: 17px; } }
.rule--unconfirmed h3::after {
  content: "Unconfirmed";
  display: inline-block;
  margin-left: .6em;
  padding: .12em .5em;
  border: 1px solid rgba(133,183,235,.4);
  border-radius: 3px;
  color: #85B7EB;
  font-size: .62em;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
  vertical-align: middle;
}
.rule__cite {
  display: inline-block;
  color: var(--mid-grey);
  font-size: .88em;
  font-style: italic;
}

.qa {
  padding: 22px 0;
  border-bottom: 1px solid rgba(255,255,255,.11);
}
.qa:first-of-type { border-top: 1px solid rgba(255,255,255,.11); }
.qa h3 { margin-bottom: .4em; color: var(--white); }
.qa p { margin: 0; max-width: 74ch; }

/* ---------- prose (legal pages) ---------- */

.prose { max-width: 74ch; }
.prose h2 { margin-top: 2.2em; }
.prose h3 { margin-top: 1.8em; }
.prose ul, .prose ol { padding-left: 1.3em; margin: 0 0 1.15em; }
.prose li { margin-bottom: .5em; }
.prose code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9em; background: rgba(255,255,255,.08);
  padding: 2px 6px; border-radius: 4px;
}
.prose__updated { font-size: 13.5px; color: var(--mid-grey); }

.callout {
  border-left: 3px solid var(--accent);
  background: rgba(56,182,255,.07);
  padding: 18px 22px; margin: 0 0 1.4em;
  border-radius: 0 8px 8px 0;
}
.callout p:last-child { margin-bottom: 0; }

/* ---------- footer ---------- */

.footer { background: var(--navy-dark); padding: 62px 0 42px; border-top: var(--hairline); }
/* Single column by default, widening at 900px.
   NOT `minmax(220px, 1.4fr) repeat(auto-fit, minmax(150px, 1fr))` — an explicit
   track cannot wrap, so on a 374px-wide viewport that forced a 220px column plus
   a 150px column and pushed the footer ~54px past the right edge. The `min(100%,
   190px)` floor is what lets the tracks collapse to one on narrow screens. */
.footer__grid {
  display: grid; gap: 34px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
}
.footer__brand { grid-column: 1 / -1; }
@media (min-width: 900px) {
  .footer__grid { grid-template-columns: 1.5fr 1fr 1fr 1fr; }
  .footer__brand { grid-column: auto; }
}
.footer__logo img { width: 176px; display: block; margin-bottom: 16px; }
.footer h4 {
  font-family: var(--font-sans); font-size: 11.5px; font-weight: 600;
  letter-spacing: 1.6px; text-transform: uppercase; color: var(--mid-grey);
  margin: 0 0 14px;
}
.footer ul { list-style: none; padding: 0; margin: 0; font-size: 14.5px; }
.footer li { margin-bottom: 9px; }
.footer a { color: var(--lightblue-100); text-decoration: none; }
.footer a:hover { color: var(--white); text-decoration: underline; }

/* Shared footer social treatment — 42px rounded-square bordered buttons, not
   bare glyphs. Identical on sojourn.tax and sojourn-group.com. Only ever link a
   channel that is actually LIVE: TikTok and LinkedIn are deliberately absent
   because those accounts do not exist yet (a dead link to an unclaimed profile
   is worse than no link). */
.footer-socials { display: flex; gap: 12px; margin-top: 4px; }
.footer-socials a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 9px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: var(--lightblue-100);
  transition: color .2s ease, border-color .2s ease, background .2s ease;
}
.footer-socials a:hover {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.42);
  background: rgba(255, 255, 255, 0.05);
}
.footer-socials svg { width: 18px; height: 18px; fill: currentColor; display: block; }

.footer__base {
  margin-top: 44px; padding-top: 26px;
  border-top: 1px solid rgba(255,255,255,.1);
  display: flex; flex-wrap: wrap; gap: 14px 26px; align-items: center;
  font-size: 13.5px; color: var(--mid-grey);
}
.footer__base p { margin: 0; }

/* ---------- reveal-on-scroll (progressive; visible without JS) ---------- */

.reveal { opacity: 1; }
.js .reveal { opacity: 0; transform: translateY(14px); transition: opacity .55s ease, transform .55s ease; }
.js .reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; }
}
