/* ============================================================================
   ForiForeign · the light atmosphere layer
   ----------------------------------------------------------------------------
   landing.css carries the LAYOUT of the public pages (grids, lanes, the train,
   the step list) and, appended after it, a ~350-line block that repaints those
   pages as dark navy glass over a video. This file keeps the layout and
   replaces the paint: one light, colourful, uniform surface across every
   signed-out page.

   Rules of the house, applied throughout:
     · Colour comes from /ff-tokens.css. Literal hex appears here only for the
       atmosphere gradients, where a token would hide what the value is doing.
     · Every text/background pair is at or above 4.5:1 (3:1 for large type).
       Ratios are recorded where the pair is not obvious.
     · Depth is carried by ONE shadow scale and ONE radius scale, both tokens.
       Nothing floats without a reason.
     · Motion is opt-out: every animation here is inside a guard that renders
       the final state immediately under prefers-reduced-motion.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   1. THE ATMOSPHERE
   The brief asks for a background that is never flat, dull or empty, and never
   loud. Four very low-alpha colour fields at different scales do that: they
   read as light falling across a surface rather than as a gradient. Total ink
   over the page ground is under 7%, so every one of them is a background the
   contrast maths can treat as ~#F6F9FE.

   The dark video layers are kept in the DOM (other scripts reference them) and
   repainted here. #mktBg / #ff-bgvideo become the colour field; the veil layers
   become a soft vignette that keeps the page edges from going flat.
   --------------------------------------------------------------------------- */
:root {
  /* A warm ivory ground, not a cool grey one. Grey-blue is the default every
     light interface falls into; ivory reads as paper, gives a white card
     something to be crisp against, and is the single change that stops this
     looking like every other light SaaS page. */
  --ff-ground: var(--color-ground);

  /* The two tonal fields are the product's own two lanes — study amber and
     remote-work teal — rather than colours picked for looking nice. Brand blue
     sits under the hero, where the action is. No violet: a blue-and-purple
     wash is the house style of generated interfaces and is exactly what this
     page should not look like. */
  --ff-atm-study: rgba(168, 91, 0, .055);
  --ff-atm-work:  rgba(15, 118, 110, .05);
  --ff-atm-brand: rgba(11, 94, 215, .05);

  /* Surfaces come from the token layer so the app and the public site cannot
     drift apart: ff-tokens.css is where the ivory and its warm hairlines are
     defined, and both surfaces read the same values. */
  --ff-sheet: var(--color-surface);
  --ff-well:  var(--color-well);
  --ff-hair:  var(--color-hair);
}

html { background: var(--ff-ground); }

body {
  background: transparent !important;
  color: var(--color-text) !important;
}

/* The colour field. Fixed, so it does not scroll with the content and cannot
   cost a repaint per frame. */
/* Superseded by section 25 (SILK), which repaints this element entirely.
   Left here as the record of what it was: three flat radial washes on an ivory
   ground, which read as silver on a cool-calibrated laptop panel. */

/* The video was a 5.9 MB decorative download for a dark surface that no longer
   exists. It is hidden rather than removed so the existing loader scripts stay
   harmless, and the bytes are never shown. */

/* A whisper of vignette. Without it the corners of a large monitor go flat,
   which is exactly the "dull and empty" the brief rules out. */
#mktOverlay, #ff-bgveil {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 0%, transparent 55%, rgba(92, 72, 44, .045) 100%) !important;
}

/* ---------------------------------------------------------------------------
   2. PAINT ORDER
   landing.css lifts only `header.top, main, footer` above the fixed layers.
   Anything else holding content is painted underneath and is invisible
   regardless of its colour — this is what made three pages render as an empty
   photograph. Everything that can hold content is lifted here, once.
   --------------------------------------------------------------------------- */
header.top, header:not(.top), main, footer,
body > .wrap, body > section, body > .bar {
  position: relative;
  z-index: var(--z-content);
}
/* .sticky, .wa and .wa-support are position:fixed by design. Giving them
   position:relative here dropped the support button out of its corner and half
   off the left edge; they only ever needed the z-index. */
.sticky, .wa, .wa-support { z-index: var(--z-fab); }
header.top, header:not(.top) { z-index: var(--z-header); }
.sticky { z-index: var(--z-nav); }

/* ---------------------------------------------------------------------------
   3. TYPE
   The dark block painted every heading #FFFFFF !important and every paragraph
   #DCE9FF !important. Both are handed back to the token scale, which is ink on
   light: #0B1B3A on #F6F9FE is 14.8:1, #3D4B66 is 8.4:1, #5A6B82 is 5.3:1.

   Hierarchy is built from size AND weight AND colour together, so a heading is
   never merely "bigger text". Sizes step deliberately and stop climbing: the
   hero is the only display-scale item on any page.
   --------------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6,
b, strong, legend, summary, th, label {
  color: var(--color-text) !important;
  text-shadow: none !important;
  opacity: 1 !important;
}
p, li, td, figcaption, .lead, .sub, .small, .facts span {
  color: var(--color-text-2) !important;
}
.muted, small, .note, .meta { color: var(--color-muted) !important; }

h1 {
  font: var(--fw-bold) var(--fs-5xl) / var(--lh-tight) var(--font-display);
  letter-spacing: var(--ls-display);
  margin: 0 0 var(--sp-3);
  text-wrap: balance;
}
.hero h1 { font-size: var(--fs-6xl); }
h2 {
  font: var(--fw-bold) var(--fs-4xl) / var(--lh-heading) var(--font-display);
  letter-spacing: var(--ls-heading);
  margin: 0 0 var(--sp-3);
  text-wrap: balance;
}
h3 {
  font: var(--fw-semibold) var(--fs-2xl) / var(--lh-heading) var(--font-display);
  letter-spacing: var(--ls-heading);
  margin: 0 0 var(--sp-2);
}
h4, summary {
  font: var(--fw-semibold) var(--fs-lg) / var(--lh-ui) var(--font-ui);
  letter-spacing: 0;
}
p, li, td { line-height: var(--lh-body); }

/* The eyebrow is metadata, so it is set as metadata: small, spaced, uppercase,
   in the data face. #0B5ED7 on the ground is 5.4:1. */
.eyebrow {
  font: var(--fw-medium) var(--fs-2xs) / 1.5 var(--font-data);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--color-brand-text) !important;
}

/* Measure. Long-form prose is capped so no line runs past what the eye tracks
   comfortably; a paragraph inside a narrow card is already capped by the card. */
p, li { max-width: var(--measure); }
.lead { max-width: 58ch; font-size: var(--fs-xl); color: var(--color-text-2) !important; }
td p, td li, .card p, .card li, .plan p, .plan li { max-width: none; }

/* ---------------------------------------------------------------------------
   4. SURFACES
   Not everything is a card. Three levels only:
     · open      — sits directly on the atmosphere, no border, no shadow
     · panel     — hairline border, no shadow: grouping without weight
     · raised    — border + soft shadow: something you can act on
   The dark block gave every panel the same navy glass, which is what made the
   pages read as a stack of identical rectangles.
   --------------------------------------------------------------------------- */
main, section, .wrap { background: transparent !important; }

.card, .plan, .step, .door, .case, .doc, .ledger, .panel, .iso, details {
  background: var(--color-surface) !important;
  border: 1px solid var(--color-hair) !important;
  border-radius: var(--radius-xl) !important;
  color: var(--color-text) !important;
  box-shadow: var(--shadow-sm) !important;
}
.card, .plan, .door, .case { padding: var(--sp-6) !important; }
details { padding: var(--sp-4) var(--sp-5) !important; }
details + details { margin-top: var(--sp-2); }

/* Raised: the things a visitor is meant to reach for. */
.plan, .door {
  box-shadow: var(--shadow-md) !important;
}

/* A tinted panel for the one item per group that carries the recommendation.
   #0B1B3A on #E8F0FE is 13.4:1. */
.plan.featured, .plan[data-featured], .highlight {
  background: var(--color-brand-soft) !important;
  border-color: var(--color-hair-brand) !important;
}

/* ---------------------------------------------------------------------------
   5. CHROME
   The header is glass in the literal sense now: white at 82% over the colour
   field, with a hairline and a blur. It reads as a surface, not as a bar.
   --------------------------------------------------------------------------- */
header.top, header:not(.top) {
  background: rgba(255, 255, 255, .82) !important;
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid var(--color-hair) !important;
}
header .brand, header .brand span { color: var(--color-text) !important; }
header .brand b { color: var(--color-mark) !important; }   /* logo lockup only */
header nav a { color: var(--color-text-2) !important; }
header nav a:hover { color: var(--color-text) !important; }

footer {
  background: transparent !important;
  border-top: 1px solid var(--color-hair);
  color: var(--color-muted) !important;
}
footer a { color: var(--color-text-2) !important; }

/* ---------------------------------------------------------------------------
   6. ACTIONS
   One button language everywhere. Primary is the brand blue at 5.8:1 against
   white type; secondary is ink on white with a hairline; ghost is text only.
   Every one of them is at least 44px tall, which is the touch minimum.
   --------------------------------------------------------------------------- */
.btn, button, a.cta, a.btn {
  font: var(--fw-semibold) var(--fs-md) / 1 var(--font-ui);
  border-radius: var(--radius-md);
  min-height: var(--tap-min);
  padding: 0 var(--sp-5);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out),
              transform var(--dur-1) var(--ease-out);
}
a.cta, a.btn.primary, button.btn.primary, .btn.primary,
.bar nav a.cta, header nav a.cta, header.top nav a.cta, .top .cta {
  background: var(--color-brand) !important;
  color: var(--color-on-brand) !important;
  border: 1px solid transparent !important;
  box-shadow: var(--shadow-sm) !important;
}
a.cta:hover, a.btn.primary:hover, button.btn.primary:hover, .btn.primary:hover,
header.top nav a.cta:hover, .top .cta:hover {
  background: var(--color-brand-strong) !important;
  box-shadow: var(--shadow-md) !important;
  transform: translateY(-1px);
}
a.cta:active, .btn.primary:active { transform: translateY(0); }

.btn.ghost, .ghost, button.ghost {
  background: var(--color-surface) !important;
  color: var(--color-text) !important;
  border: 1px solid var(--color-hair-2) !important;
}
.btn.ghost:hover, .ghost:hover, button.ghost:hover {
  border-color: var(--color-hair-brand) !important;
  background: var(--color-brand-soft) !important;
}

/* Focus is never removed, only styled. */
a:focus-visible, button:focus-visible, .btn:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible, summary:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
  border-radius: var(--radius-sm);
}

/* ---------------------------------------------------------------------------
   7. FORMS
   --------------------------------------------------------------------------- */
input, select, textarea {
  background: var(--color-surface) !important;
  color: var(--color-text) !important;
  border: 1px solid var(--color-hair-2) !important;
  border-radius: var(--radius-md) !important;
  min-height: var(--tap-min);
  padding: 0 var(--sp-3);
  font: var(--fw-regular) var(--fs-md) / var(--lh-ui) var(--font-ui);
}
textarea { padding: var(--sp-3); min-height: 96px; line-height: var(--lh-body); }
input::placeholder, textarea::placeholder { color: var(--color-muted); }
input:focus, select:focus, textarea:focus {
  border-color: var(--color-brand) !important;
  box-shadow: var(--shadow-focus);
}

/* ---------------------------------------------------------------------------
   8. TABLES
   Data is set in the data face so columns of numbers line up, and the head is
   a tinted band rather than a saturated fill.
   --------------------------------------------------------------------------- */
table { background: transparent !important; border-color: var(--color-hair) !important; }
thead th, th.g, .cmp th.g {
  background: var(--color-well) !important;
  color: var(--color-text) !important;
  border-bottom: 1px solid var(--color-hair-2) !important;
  font: var(--fw-semibold) var(--fs-sm) / var(--lh-ui) var(--font-ui);
  text-align: start;
}
td, th { border-color: var(--color-hair) !important; }
tbody tr:nth-child(even) td { background: rgba(11, 27, 58, .018); }
td.num, .num, .amt, .price { font-family: var(--font-data); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
   9. THE TWO LANES
   Study and remote work are peers, so neither is the primary colour. They are
   separated by hue, not by weight. Both edge colours clear 4.5:1 on white:
   #0F766E teal 5.1:1, #A85B00 amber 5.0:1 — the previous #2dd4bf (1.8:1) and
   #F5B841 (1.9:1) were chosen for a dark surface and are unreadable on light.
   --------------------------------------------------------------------------- */
:root { --ff-lane-study: #A85B00; --ff-lane-work: #0F766E; }

.lane-c-study, .brandline .bl-study { color: var(--ff-lane-study) !important; }
.lane-c-work,  .brandline .bl-work  { color: var(--ff-lane-work) !important; }
.lane-row { border-bottom: 1px solid var(--color-hair) !important; }
.lane-n { color: var(--color-muted) !important; opacity: 1 !important; }
.lane-head { background: var(--color-well) !important; border-radius: var(--radius-md); }
.brandline .bl-sep { color: var(--color-hair-2) !important; }

/* ---------------------------------------------------------------------------
   10. SUPPORT BUTTON
   The WhatsApp green is a brand colour and stays. White on it is 1.98:1, so
   the label is ink: 8.6:1.
   --------------------------------------------------------------------------- */
.wa, .wa-support {
  background: #25D366 !important;
  color: var(--color-ink-surface) !important;
  border: 1px solid rgba(11, 27, 58, .12) !important;
  box-shadow: var(--shadow-md) !important;
}
.wa svg, .wa-support svg { fill: var(--color-ink-surface) !important; }

/* ---------------------------------------------------------------------------
   11. MOTION
   Purposeful only: things arrive once as you reach them, and controls answer
   the pointer. Nothing loops in the reader's peripheral vision except the
   atmosphere itself, which moves over 40 seconds and is barely perceptible.

   Everything below is inside `html.ff-motion`, a class set by the page script
   only when the visitor has NOT asked for reduced motion. With the class
   absent every element renders in its final state, which is also what happens
   if the script never runs.
   --------------------------------------------------------------------------- */
html.ff-motion .ff-reveal {
  opacity: 0;
  transform: translateY(14px);
}
html.ff-motion .ff-reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-4) var(--ease-out),
              transform var(--dur-4) var(--ease-out);
}
/* Children of a revealed group arrive in sequence rather than as a block. The
   delay is capped at six steps so a long grid never feels slow. */
html.ff-motion .ff-reveal.is-in > * { animation: ff-rise var(--dur-3) var(--ease-out) both; }
html.ff-motion .ff-reveal.is-in > :nth-child(1) { animation-delay: 0ms; }
html.ff-motion .ff-reveal.is-in > :nth-child(2) { animation-delay: 60ms; }
html.ff-motion .ff-reveal.is-in > :nth-child(3) { animation-delay: 120ms; }
html.ff-motion .ff-reveal.is-in > :nth-child(4) { animation-delay: 180ms; }
html.ff-motion .ff-reveal.is-in > :nth-child(5) { animation-delay: 240ms; }
html.ff-motion .ff-reveal.is-in > :nth-child(n+6) { animation-delay: 300ms; }
@keyframes ff-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* Card hover: a lift small enough to read as "this is reachable" rather than
   as an animation. Pointer-only, so a touch device never gets a stuck state. */
@media (hover: hover) and (pointer: fine) {
  html.ff-motion .card, html.ff-motion .plan, html.ff-motion .door, html.ff-motion .step {
    transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out),
                border-color var(--dur-2) var(--ease-out);
  }
  html.ff-motion .card:hover, html.ff-motion .plan:hover,
  html.ff-motion .door:hover, html.ff-motion .step:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg) !important;
    border-color: var(--color-hair-brand) !important;
  }
}

/* The atmosphere drifts. 40s, 2% of the viewport, and it never moves under the
   reader's eye fast enough to be noticed as motion — only as "alive". */
html.ff-motion #mktBg, html.ff-motion #ff-bgvideo {
  animation: ff-drift 40s var(--ease-in-out) infinite alternate;
  will-change: transform;
}
@keyframes ff-drift {
  from { transform: translate3d(0, 0, 0) scale(1.02); }
  to   { transform: translate3d(-1.5%, 1%, 0) scale(1.06); }
}

/* Parallax: the colour field lags the page slightly. --ff-par is written by the
   page script from a rAF-throttled scroll listener, so nothing here reads
   layout during a scroll. */
html.ff-motion #mktBg, html.ff-motion #ff-bgvideo {
  translate: 0 calc(var(--ff-par, 0) * 1px);
}

/* The one rule that outranks all of the above. */
@media (prefers-reduced-motion: reduce) {
  html.ff-motion .ff-reveal,
  html.ff-motion .ff-reveal.is-in,
  html.ff-motion .ff-reveal.is-in > * {
    opacity: 1 !important; transform: none !important;
    animation: none !important; transition: none !important;
  }
  html.ff-motion #mktBg, html.ff-motion #ff-bgvideo {
    animation: none !important; translate: none !important; transform: none !important;
  }
  * { scroll-behavior: auto !important; }
}

/* ---------------------------------------------------------------------------
   12. RESPONSIVE
   The desktop rule the brief asks for: use the width, but not all of it. The
   container is capped at the token width and centred, so a 1440px monitor gets
   a composed page rather than one stretched line of text.
   --------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--container-lg);
  margin-inline: auto;
  padding-inline: var(--sp-5);
  box-sizing: border-box;
}
body > .wrap { max-width: var(--container); }   /* long-form documents read narrower */

@media (min-width: 1440px) {
  .wrap { max-width: var(--container-xl); }
  body > .wrap { max-width: var(--container); }
}

@media (max-width: 720px) {
  h1 { font-size: var(--fs-4xl); }
  .hero h1 { font-size: var(--fs-5xl); }
  h2 { font-size: var(--fs-3xl); }
  .lead { font-size: var(--fs-lg); }
  .wrap { padding-inline: var(--sp-4); }
  .card, .plan, .door, .case { padding: var(--sp-5) !important; }
}

/* Nothing overflows its column, ever. Wide data scrolls inside its own box
   rather than pushing the page sideways. */
html, body { overflow-x: hidden; }
.table-scroll, .cmp-wrap, .scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
img, svg, video, canvas { max-width: 100%; height: auto; }
pre, code { overflow-x: auto; max-width: 100%; }

/* ---------------------------------------------------------------------------
   13. INVERTED SURFACES
   A light page is not an all-white page. The closing block is a deliberate ink
   slab — it ends the page with weight and makes the final action unmissable —
   and `.lane-head` and the app's dark chrome work the same way. Inverting the
   surface has to invert the TYPE with it, which is exactly what the first pass
   got wrong: the ink heading stayed ink and vanished into the ink slab (1:1).

   Everything inside an inverted surface is declared here, once, so a new
   element dropped into one cannot inherit the wrong colour.
   #FFFFFF on #0B1B3A is 15.9:1 · #C3CDDE is 10.5:1 · #7EB6FF link is 6.9:1.
   --------------------------------------------------------------------------- */
.close, .ff-invert, .stats {
  background: var(--color-ink-surface) !important;
  color: #FFFFFF !important;
  border: 0 !important;
  border-radius: var(--radius-xl);
}
.close h1, .close h2, .close h3, .close h4, .close b, .close strong, .close summary,
.stats h1, .stats h2, .stats h3, .stats em,
.ff-invert h1, .ff-invert h2, .ff-invert h3, .ff-invert h4, .ff-invert b, .ff-invert strong {
  color: #FFFFFF !important;
}
.close p, .close li, .close td, .close small, .close .muted, .close span,
.stats p, .stats span, .stats li,
.ff-invert p, .ff-invert li, .ff-invert small, .ff-invert .muted {
  color: #C3CDDE !important;
}
.close a, .ff-invert a { color: #7EB6FF !important; }
.close a:hover, .ff-invert a:hover { color: #FFFFFF !important; }
/* The primary action keeps its own fill and white type — it must not be
   repainted by the link rule above. */
.close a.cta, .close a.btn.primary, .close .btn.primary,
.ff-invert a.cta, .ff-invert .btn.primary {
  background: var(--color-brand) !important;
  color: var(--color-on-brand) !important;
}
.close .ghost, .ff-invert .ghost {
  background: transparent !important;
  color: #FFFFFF !important;
  border: 1px solid rgba(255, 255, 255, .38) !important;
}
.close .ghost:hover, .ff-invert .ghost:hover { background: rgba(255, 255, 255, .10) !important; }

/* ---------------------------------------------------------------------------
   14. CORRECTIONS FROM THE MEASURED AUDIT
   Each of these was a real failure on the light surface, with its measured
   ratio before and after. Two of them (the wordmark and the header pill) were
   introduced by section 5 of this file and are corrected at the source.
   --------------------------------------------------------------------------- */

/* The wordmark. #1683FF is the logo blue and reads 3.63:1 on white — fine as a
   graphic, not as 18px type. The deeper brand blue is 5.4:1 and is visually
   the same mark. */
header .brand b, .brand b, nav a.brand b { color: var(--color-brand) !important; }

/* The header sign-in pill carries its fill inline (background:#0B1B3A;color:#fff).
   Section 5's `header nav a` rule repainted its label to body ink and dropped it
   to 1.95:1 on its own navy. Any nav link that is a filled pill keeps white. */
header nav a[style*="background"], header nav a.cta, header nav a.btn { color: #FFFFFF !important; }

/* Semantic greens and links tuned for white rather than for the old navy.
   #4ade80 on white 1.74:1 -> #15803D 4.6:1 · #1683FF 3.48:1 -> #0B5ED7 5.4:1 */
details .tag, .ok, .tick, .yes { color: #15803D !important; border-color: rgba(21, 128, 61, .35) !important; }
a[style*="#1683FF"], a[style*="1683ff"] { color: var(--color-brand) !important; }

/* Text that kept a for-dark colour on a now-light surface. These were set for
   the navy glass and are simply wrong here; they return to the token scale. */
.facts em, .facts span, .fact em, .stat em, .stat span,
.iso em, .iso span, .kill em, .kill span { color: var(--color-text-2) !important; }
.lane-c-study em, .lane-c-work em, .lane-head em, .lane-head span { color: var(--color-text-2) !important; }
h3, .card h3, .step h3, .door h3 { color: var(--color-text) !important; }

/* ---------------------------------------------------------------------------
   15. LAYOUT REPAIRS
   --------------------------------------------------------------------------- */

/* Cards in a row are equal height because the grid stretches them, which left
   the shorter card with its link floating in the middle of a pool of empty
   space. The body grows and the action sits on the floor of the card, so a row
   of cards has one baseline for its actions. */
.door, .card, .plan {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.door .go, .card .go, .plan .go, .door > a:last-child, .card > a.go {
  margin-top: auto;
  padding-top: var(--sp-3);
  align-self: flex-start;
}

/* Section heads stay left-aligned on every width. Centring a block of text
   moves the start of every line, so the eye has to re-find it each time, and it
   detaches the head from the left edge of the grid it introduces. The measure
   is capped instead — that is what stops a head running the full 1280px — and
   the space it leaves on the right is deliberate, not a void. */
.sec-head { max-width: 62ch; text-align: start; margin-inline: 0; }
.sec-head p, .sec-head .lead { margin-inline: 0; }

/* Sections were separated by whatever margin their content happened to carry,
   which produced 250px holes in some places and none in others. One rhythm. */
main > section { padding-block: var(--sp-16); }
main > section + section { padding-top: var(--sp-12); }
@media (max-width: 720px) { main > section { padding-block: var(--sp-10); } }

/* A badge that sits on a card's edge is a positioned label, not a chip: it
   keeps the brand fill and white type (5.8:1), and the card must not clip it. */
.plan .tag, .card .badge, .plan .badge {
  background: var(--color-brand) !important;
  color: var(--color-on-brand) !important;
  border: 0 !important;
  box-shadow: var(--shadow-sm);
  z-index: 1;
}
.plan, .grid, .cards { overflow: visible; }

/* The stats numerals keep the mint accent they were designed with: on the ink
   band it reads 10.8:1, and it is the one place on the light pages where a
   cool accent carries data rather than decoration. */
.stats b { color: #7EE6FF !important; }

/* ---------------------------------------------------------------------------
   16. THE CONTAINER, FOR PAGES THAT NEVER HAD ONE
   partners.html and pricing.html put their content straight into <main> with
   no .wrap, so on a wide monitor the text ran from edge to edge with a 22px
   gutter — the "extremely narrow margins / uneven section boundaries" the brief
   rules out. main now carries the same measure and gutters as .wrap, and a
   .wrap inside it simply inherits the width rather than nesting a second cap.
   --------------------------------------------------------------------------- */
main {
  width: 100%;
  max-width: var(--container-lg);
  margin-inline: auto;
  padding-inline: var(--sp-5);
  box-sizing: border-box;
}
main > .wrap, main .wrap { max-width: none; padding-inline: 0; }
@media (min-width: 1440px) { main { max-width: var(--container-xl); } }
@media (max-width: 720px)  { main { padding-inline: var(--sp-4); } }

/* A full-bleed band still spans the viewport: it breaks out of the container
   rather than the container being widened for it. */
main > .stats, main > .ff-bleed {
  width: 100vw;
  max-width: 100vw;
  margin-inline: calc(50% - 50vw);
  padding-inline: var(--sp-5);
  border-radius: 0 !important;
}

/* ===========================================================================
   17. REFINEMENT PASS
   The first pass made the site light and readable. This one makes it specific:
   a warmer ground, a rhythm of surfaces rather than one continuous wash, and
   type that carries hierarchy without shouting.
   =========================================================================== */

/* --- 17.1 Surfaces on ivory -----------------------------------------------
   Cards were white on a cool grey-blue, which is the combination that reads as
   "generic light theme". White on warm ivory reads as paper on a desk: the
   card edge is legible without a heavy border, and the hairline can be warm
   rather than a grey line drawn over everything. */
.card, .plan, .step, .door, .case, .doc, .ledger, .panel, .iso, details {
  background: var(--ff-sheet) !important;
  border-color: var(--ff-hair) !important;
  box-shadow: 0 1px 2px rgba(92, 72, 44, .05), 0 8px 24px -18px rgba(92, 72, 44, .30) !important;
}
.plan, .door {
  box-shadow: 0 1px 2px rgba(92, 72, 44, .06), 0 18px 40px -28px rgba(92, 72, 44, .42) !important;
}
thead th, th.g, .cmp th.g { background: var(--ff-well) !important; border-bottom-color: var(--ff-hair) !important; }
td, th { border-color: var(--ff-hair) !important; }
tbody tr:nth-child(even) td { background: rgba(92, 72, 44, .022); }
hr, .rule, .divider { border: 0; border-top: 1px solid var(--ff-hair); }

/* --- 17.2 Rhythm ----------------------------------------------------------
   Not every section is coloured. The default is the ivory ground; every other
   major section lifts onto a white sheet, and one band per page inverts. That
   alternation is what gives a long page structure without adding a single
   decorative element. */
main > section:nth-of-type(even) {
  background: linear-gradient(180deg, rgba(255,255,255,0) 0%, var(--ff-sheet) 8%, var(--ff-sheet) 92%, rgba(255,255,255,0) 100%);
}
main > section.hero, main > section:has(.stats) { background: none; }

/* --- 17.3 Type ------------------------------------------------------------
   Sizes were already stepped; this tightens the two that carry the most
   weight. The hero drops a step — at 44px it was loud rather than confident —
   and headings get slightly tighter tracking, which is what makes a bold
   sans read as designed rather than as default. */
.hero h1 { font-size: clamp(2rem, 1.2rem + 2.6vw, 2.75rem); letter-spacing: -.028em; }
h2 { font-size: clamp(1.375rem, 1.1rem + 1vw, 1.75rem); }
h3 { font-size: var(--fs-xl); }
.lead { font-size: var(--fs-lg); line-height: 1.65; max-width: 54ch; }
p { max-width: 62ch; }

/* Numerals in the data face wherever they are the point, so columns of figures
   align and a price cannot jitter as it changes. */
.price, .amt, .num, .stats b, .n, .code { font-variant-numeric: tabular-nums; }

/* --- 17.4 Motion, trimmed -------------------------------------------------
   The drift was a 40s loop on the whole colour field. Slower and shorter: it
   should register as the page being alive, never as something moving. */
@keyframes ff-drift {
  from { transform: translate3d(0, 0, 0) scale(1.01); }
  to   { transform: translate3d(-1%, .6%, 0) scale(1.03); }
}
html.ff-motion #mktBg, html.ff-motion #ff-bgvideo { animation-duration: 64s; }

/* Hover lifts the card by a pixel and warms its edge. Anything more turns a
   grid of cards into a trampoline. */
@media (hover: hover) and (pointer: fine) {
  html.ff-motion .card:hover, html.ff-motion .plan:hover,
  html.ff-motion .door:hover, html.ff-motion .step:hover {
    transform: translateY(-1px);
    border-color: var(--color-hair-brand) !important;
    box-shadow: 0 2px 4px rgba(92,72,44,.06), 0 24px 48px -30px rgba(92,72,44,.5) !important;
  }
}

/* --- 17.5 Alignment -------------------------------------------------------
   Everything that was centred for effect goes back to the grid. Centring is
   kept only where the element is genuinely a single short line — the closing
   action, and a stat cell whose number sits above its label. */
.wrap > p, .wrap > h1, .wrap > h2, .wrap > h3, main > section > h2,
.door, .card, .plan, .step { text-align: start; }
.acts, .close-top, .close-links, .close-social { justify-content: flex-start; }
.close { text-align: start; }
.close-top { gap: var(--sp-4); }
@media (max-width: 560px) { .acts, .close-top { justify-content: stretch; } }

/* Cards in a row are equal height because the grid stretches them. Reserving
   two lines for every heading was an attempt to align their baselines and did
   the opposite: it padded the shorter card from the top and pushed its content
   down past its neighbour. The heading takes the height it needs; the action at
   the foot of the card is what actually shares a baseline across the row. */
.grid, .cards, .doors { align-items: stretch; }

/* --- 17.6 The hero, left-aligned -----------------------------------------
   A centred hero over a centred sub-paragraph over centred buttons is the
   default arrangement of every SaaS landing page, and at three lines the lead
   makes the reader re-find the start of each line. Setting it against the left
   edge of the grid does three things: it reads faster, it lines the hero up
   with every section below it, and it stops the page looking like a template.
   The measure is capped so the column still sits in the page rather than
   running its full width. */
.hero .wrap {
  text-align: start;
  max-width: var(--container-lg);
  margin-inline: auto;
}
.hero h1 { max-width: 20ch; }
.hero .lead, .hero p { max-width: 52ch; margin-inline: 0; }
.hero .acts, .hero .facts { justify-content: flex-start; }
.hero .facts { gap: var(--sp-4) var(--sp-5); flex-wrap: wrap; }

/* On a phone the column is the full width anyway, so the only thing centring
   would add is the re-find cost. It stays left there too. */
@media (max-width: 720px) {
  .hero .wrap { text-align: start; }
  .hero .acts { flex-direction: column; align-items: stretch; }
  .hero .acts .btn, .hero .acts a { width: 100%; }
}

/* landing.css centres `.lead` with the physical longhands
   (margin-left/right:auto) and gives `.door` justify-content:flex-end so a
   card's content sits on its floor. Both were written for the centred hero and
   the tall photo-doors that are gone. Matched here with the same longhands at a
   higher specificity, rather than with !important. */
.hero .wrap .lead, .hero .wrap p { margin-left: 0; margin-right: 0; }
.hero .wrap .acts, .hero .wrap .facts { margin-left: 0; margin-right: 0; }

/* Content starts at the top of the card and the action falls to the floor,
   which is what actually lines a row of cards up. flex-end pushed the shorter
   card's whole body down and made the row look broken. */
.door, .card, .plan { justify-content: flex-start; }
.door { min-height: 0; }

/* --- 17.7 The lane colours, used consistently -----------------------------
   Study is amber, remote work is teal, everywhere they appear: the door
   eyebrow, the lane columns, the four-F line and the card edge. Using the
   brand blue for both said the two lanes were the same thing, which is the one
   idea the page exists to contradict. Both clear AA on white — #A85B00 5.0:1,
   #0F766E 5.1:1 — and both are the source of the two tonal fields behind the
   page, so the colour language is the product's own. */
.door.study .eyebrow, .lane-c-study, .brandline .bl-study, .study .eyebrow {
  color: var(--ff-lane-study) !important;
}
.door.work .eyebrow, .lane-c-work, .brandline .bl-work, .work .eyebrow {
  color: var(--ff-lane-work) !important;
}
.door.study { border-top: 3px solid var(--ff-lane-study) !important; }
.door.work  { border-top: 3px solid var(--ff-lane-work) !important; }

/* The two lane doors carry a tint of their own colour, not flat white -- the
   first thing a visitor chooses between should not look identical to a card
   listing legal links. Same idea as the destination atmosphere, stronger: this
   is a surface that wants to be noticed, so it reads at roughly double the
   opacity of the page-level colour field. */
.door.study { background: linear-gradient(180deg, rgba(168,91,0,.06), rgba(168,91,0,.02)) var(--color-surface) !important; }
.door.work  { background: linear-gradient(180deg, rgba(15,118,110,.06), rgba(15,118,110,.02)) var(--color-surface) !important; }

/* The featured pricing plan and the closing CTA panel get the brand version of
   the same treatment, so "this is the one to look at" is read from the
   surface before a word of copy is. */
.plan.featured, .plan[data-featured], .highlight, .plan.pop {
  background: linear-gradient(180deg, rgba(11,94,215,.055), rgba(11,94,215,.015)) var(--color-surface) !important;
}
.door.study:hover { border-color: var(--ff-lane-study) !important; }
.door.work:hover  { border-color: var(--ff-lane-work) !important; }

/* --- 17.8 Touch targets --------------------------------------------------
   Navigation links were 34–35px tall. A pointer copes; a thumb does not, and
   44px is the floor. The height is added as padding so the visual weight of the
   nav does not change — the row is the same, the reachable area is not. */
/* A horizontal nav: the links sit in a row, so inline-flex is right. */
header nav a, .bar nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  padding-block: 0;
}
/* A stacked list of links — a table of contents, a side nav — is one link per
   row. inline-flex collapsed them into a single run: "1 · Start2 · Documents".
   Block-level flex keeps the row and still gives the 44px target. */
.toc a, .help-nav a, nav.side a, aside nav a {
  display: flex;
  align-items: center;
  min-height: var(--tap-min);
}
header .brand, nav a.brand { min-height: var(--tap-min); display: inline-flex; align-items: center; }
.close-links a, footer a { display: inline-flex; align-items: center; min-height: 32px; }

/* --- 17.9 The destination chips ------------------------------------------
   `.cty` was pinned to 158px, which clipped every country whose name is longer
   than the box — "United Arab Emirates" lost five characters. The chip sizes to
   its content with a floor, so short names still line up and long ones are
   whole. The track scrolls, so a wider chip costs nothing. */
.cty { width: auto !important; min-width: 0; }
.cty .nm { overflow: visible; text-overflow: clip; }

/* On a phone the chip is content-width with no forced floor, so a short name
   ("UK", "Chile") stays small and several sit in one screenful, while a long
   one ("United Arab Emirates") still has room to grow. Padding and type are
   trimmed too, so the row reads as a train of small tags rather than chips
   pretending to be buttons. */
@media (max-width: 640px) {
  .cty { padding: 5px 10px !important; gap: 6px !important; height: 36px !important; font-size: 12px !important; }
  .cty .flg { width: 18px !important; height: 13px !important; }
}

/* --- 17.10 The remaining centred heads -----------------------------------
   pricing.html centres its head with `.top`, which predates the `.hero`
   pattern. Same treatment: capped measure, left edge on the grid. */
/* Scoped to main: <header class="top"> also matches a bare .top, and this
   rule was capping the whole site header at 60ch (540px) so the bar stopped
   halfway across the page and the nav wrapped. */
main .top { text-align: start !important; max-width: 60ch; margin-left: 0 !important; margin-right: 0 !important; }
main .top h1, main .top h2 { max-width: 20ch; }
main .top .seg, main .top .switcher { justify-content: flex-start; }

/* --- 17.11 A price is type, not a container ------------------------------
   landing.css groups `.price` with `.card, .panel, .plan, .step` and gives the
   set a border, which was right when they were all glass panels on navy. On the
   light page it puts every price in a box that reads as a disabled input. The
   figure carries itself: large, tight, in the data face, with the qualifier
   below it in the muted tone. */
.price, .plan .price {
  border: 0 !important;
  padding: 0 !important;
  background: none !important;
  box-shadow: none !important;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.03em;
  line-height: 1.05;
}
.plan .usd, .plan .was { display: inline-block; margin-top: var(--sp-1); }

/* ===========================================================================
   18. TRUST STRIP
   Three small photos per lane, captioned with what the photo shows rather than
   a fabricated testimonial or a name attributed to a stock image -- honesty
   about what the picture is, is what makes it trustworthy rather than the
   opposite. Cards keep the lane's own colour as a thin top edge, matching the
   door cards and the comparison rows, so the strip reads as part of the same
   two lanes rather than a bolted-on gallery.
   =========================================================================== */
.trust-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-6); margin-top: var(--sp-5); }
.trust-lane-label {
  font: var(--fw-semibold) var(--fs-sm) / 1 var(--font-ui);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  margin-bottom: var(--sp-3);
}
.trust-lane-study .trust-lane-label { color: var(--ff-lane-study); }
.trust-lane-work  .trust-lane-label { color: var(--ff-lane-work); }
.trust-cards { display: grid; grid-template-columns: 1fr; gap: var(--sp-3); }
.trust-card {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--color-hair);
  background: var(--color-surface);
  box-shadow: 0 1px 2px rgba(92, 72, 44, .05);
}
.trust-lane-study .trust-card { border-top: 3px solid var(--ff-lane-study); }
.trust-lane-work  .trust-card { border-top: 3px solid var(--ff-lane-work); }
.trust-card img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.trust-card figcaption {
  padding: var(--sp-2) var(--sp-3);
  font: var(--fw-medium) var(--fs-sm) / 1.4 var(--font-ui);
  color: var(--color-text-2);
}

@media (min-width: 860px) {
  /* On a wide screen the three photos per lane sit in a row rather than a
     column, so the strip reads as two matched rows instead of a tall stack. */
  .trust-cards { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 720px) {
  /* Two lanes side by side is too narrow a column for a photo on a phone; each
     lane's three photos stay in their own row instead, and the lanes stack. */
  .trust-grid { grid-template-columns: 1fr; gap: var(--sp-5); }
  .trust-cards { grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); }
  .trust-card figcaption { padding: 6px 8px; font-size: 11px; }
}

/* ===========================================================================
   19. THE LANE CHOOSER, THE TOP RAIL AND A HARDER EDGE
   The page used to say the same thing three times: two door cards, then a
   four-by-two comparison table, then a photo strip. One chooser now carries
   it: two buttons, one open panel, four steps of two or three words each.
   =========================================================================== */

/* --- 19.1 The rail, at the top ------------------------------------------- */
.rail-top { padding-block: var(--sp-5) var(--sp-4) !important; }
.rail-head { margin-bottom: var(--sp-3); }
.rail-top .atlas { margin: 0; }

/* --- 19.2 The two lane buttons ------------------------------------------- */
.lanepick {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}
.lanebtn {
  position: relative;
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  padding: var(--sp-4) var(--sp-5);
  min-height: 84px;
  text-align: start;
  cursor: pointer;
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-hair);
  background: var(--color-surface);
  box-shadow: 0 1px 2px rgba(92,72,44,.05);
  transition: border-color var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out),
              transform var(--dur-1) var(--ease-out);
}
.lanebtn .lane-name { font-size: var(--fs-lg); color: var(--color-text); }
.lanebtn-sub { font: var(--fw-medium) var(--fs-sm) / 1.3 var(--font-ui); color: var(--color-muted); }
.lanebtn-chev {
  position: absolute; right: var(--sp-4); top: var(--sp-5);
  width: 10px; height: 10px;
  border-right: 2px solid var(--color-muted); border-bottom: 2px solid var(--color-muted);
  transform: rotate(45deg);
  transition: transform var(--dur-2) var(--ease-out);
}
.lanebtn.is-open .lanebtn-chev { transform: rotate(-135deg); }

/* The open lane wears its own colour. The closed one stays quiet, so at a
   glance you can see which of the two you are reading. */
.lanebtn-study { border-top: 3px solid var(--ff-lane-study); }
.lanebtn-work  { border-top: 3px solid var(--ff-lane-work); }
.lanebtn-study.is-open {
  background: linear-gradient(180deg, rgba(168,91,0,.09), rgba(168,91,0,.02)) var(--color-surface);
  border-color: rgba(168,91,0,.35);
  box-shadow: 0 2px 4px rgba(92,72,44,.06), 0 18px 40px -28px rgba(168,91,0,.55);
}
.lanebtn-work.is-open {
  background: linear-gradient(180deg, rgba(15,118,110,.09), rgba(15,118,110,.02)) var(--color-surface);
  border-color: rgba(15,118,110,.35);
  box-shadow: 0 2px 4px rgba(92,72,44,.06), 0 18px 40px -28px rgba(15,118,110,.55);
}
@media (hover: hover) { .lanebtn:hover { transform: translateY(-1px); } }

/* --- 19.3 The panel: four steps and one photo --------------------------- */
.lanepanel {
  display: grid;
  grid-template-columns: 1fr 300px;
  gap: var(--sp-5);
  align-items: start;
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--color-hair);
}
html.ff-motion .lanepanel:not([hidden]) { animation: ff-rise var(--dur-3) var(--ease-out) both; }

.fsteps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); counter-reset: f; }
.fsteps li {
  counter-increment: f;
  display: grid;
  grid-template-columns: 26px auto 1fr;
  align-items: baseline;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--color-hair);
}
.fsteps li:last-child { border-bottom: 0; }
.fsteps li::before {
  content: counter(f, decimal-leading-zero);
  font: var(--fw-medium) var(--fs-2xs) / 1.6 var(--font-data);
  color: var(--color-muted);
  letter-spacing: .06em;
}
.fsteps b { font: var(--fw-bold) var(--fs-lg) / 1.2 var(--font-display); letter-spacing: -.01em; }
.fsteps span { color: var(--color-text-2); font-size: var(--fs-md); max-width: none; }
.lanepanel-study .fsteps b { color: var(--ff-lane-study); }
.lanepanel-work  .fsteps b { color: var(--ff-lane-work); }

/* The photo is the size of a photo, not a thumbnail. */
.lanephoto { margin: 0; border-radius: var(--radius-xl); overflow: hidden; }
.lanephoto img { display: block; width: 100%; aspect-ratio: 4/5; object-fit: cover; }
.lanepanel-study .lanephoto { box-shadow: 0 24px 60px -30px rgba(168,91,0,.5); }
.lanepanel-work  .lanephoto { box-shadow: 0 24px 60px -30px rgba(15,118,110,.5); }
.lane-cta { grid-column: 1 / -1; justify-self: start; margin-top: var(--sp-2); }

@media (max-width: 760px) {
  .lanepick { grid-template-columns: 1fr 1fr; gap: var(--sp-2); }
  .lanebtn { padding: var(--sp-3); min-height: 0; }
  .lanebtn .lane-name { font-size: var(--fs-md); }
  .lanebtn-sub { display: none; }
  .lanebtn-chev { display: none; }
  .lanepanel { grid-template-columns: 1fr; }
  .lanephoto img { aspect-ratio: 16/10; }
}

/* --- 19.4 Proof photos, larger ------------------------------------------ */
#trust-strip .trust-grid { grid-template-columns: repeat(4, 1fr); gap: var(--sp-4); }
#trust-strip .trust-card img { aspect-ratio: 3/4; }
#trust-strip .trust-card figcaption {
  font: var(--fw-semibold) var(--fs-sm) / 1.3 var(--font-ui);
  color: var(--color-text);
}
@media (max-width: 760px) {
  #trust-strip .trust-grid { grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
}

/* --- 19.5 The social row ------------------------------------------------ */
.soc-soon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 9px;
  border: 1px solid var(--color-hair);
  color: var(--color-muted);
  opacity: .55;
}

/* --- 19.6 A harder edge -------------------------------------------------
   The closing block was an ink slab that read as a different site. It keeps
   its weight but joins this one: the page ground, a hairline, and the action
   carrying the colour instead of the box. */
.close {
  background: linear-gradient(180deg, rgba(11,94,215,.06), rgba(11,94,215,.015)) var(--color-surface) !important;
  color: var(--color-text) !important;
  border: 1px solid var(--color-hair-brand) !important;
}
.close h1, .close h2, .close h3, .close b, .close strong { color: var(--color-text) !important; }
.close p, .close li, .close small, .close .muted, .close span { color: var(--color-text-2) !important; }
.close a { color: var(--color-brand) !important; }
.close a:hover { color: var(--color-brand-strong) !important; }
.close .ghost { background: var(--color-surface) !important; color: var(--color-text) !important; border: 1px solid var(--color-hair-2) !important; }
.close-social a, .close-social .soc-soon { border-color: var(--color-hair) !important; }
.close-social a { color: var(--color-text-2) !important; }

/* [hidden] must win over any display a component sets, or a panel that is
   supposed to be closed simply stays open. */
[hidden] { display: none !important; }

/* The four steps are short, so the photo beside them was taller than the list
   and left a hole under it. The panel now sizes the photo to the row instead
   of the other way round. */
.lanepanel { align-items: stretch; }
.lanepanel .lanephoto { height: 100%; }
.lanepanel .lanephoto img { height: 100%; aspect-ratio: auto; min-height: 260px; }
.lanepanel .fsteps { align-content: start; }
@media (max-width: 760px) {
  .lanepanel .lanephoto img { height: auto; aspect-ratio: 16/10; min-height: 0; }
}

/* ===========================================================================
   20. HARDER EDGE
   The review was blunt and correct: this read as a comfortable millennial
   layout — soft radii, mid-weight type, polite spacing. The product is a
   machine that files applications; it should look like one. Sharper corners,
   heavier display type, tighter tracking, real glass on the chrome, and
   motion that is felt rather than watched.
   =========================================================================== */
:root {
  /* Corners come down hard. A 16px radius on everything is the single biggest
     reason a UI reads as friendly-consumer rather than technical. */
  --radius-sm: 3px; --radius-md: 5px; --radius-lg: 7px; --radius-xl: 9px;
  /* Display type gets heavier and tighter. */
  --ls-display: -.04em; --ls-heading: -.025em;
}

/* --- 20.1 Type with weight ---------------------------------------------- */
.hero h1, h1 { font-weight: 800; }
h2 { font-weight: 800; letter-spacing: -.025em; }
.hero h1 { letter-spacing: -.042em; }

/* Eyebrows become machine labels: monospace, wide, small, uppercase. */
.eyebrow, .trust-lane-label, .rail-head .eyebrow {
  font-family: var(--font-data);
  font-size: 10.5px;
  letter-spacing: .16em;
  font-weight: var(--fw-medium);
}

/* --- 20.2 Real glass on the chrome -------------------------------------- */
header.top, header:not(.top) {
  background: rgba(251, 250, 247, .72) !important;
  -webkit-backdrop-filter: saturate(1.8) blur(20px);
  backdrop-filter: saturate(1.8) blur(20px);
  border-bottom: 1px solid rgba(11, 27, 58, .08) !important;
}
.sticky {
  -webkit-backdrop-filter: saturate(1.8) blur(20px);
  backdrop-filter: saturate(1.8) blur(20px);
}

/* --- 20.3 Buttons that look pressed, not painted ------------------------- */
.btn, button, a.cta, a.btn {
  border-radius: var(--radius-md);
  letter-spacing: -.005em;
  font-weight: var(--fw-semibold);
}
a.cta, a.btn.primary, button.btn.primary, .btn.primary,
.bar nav a.cta, header nav a.cta, header.top nav a.cta, .top .cta {
  background: linear-gradient(180deg, #1568E6, var(--color-brand)) !important;
  box-shadow: 0 1px 0 rgba(255,255,255,.22) inset,
              0 1px 2px rgba(11,27,58,.20),
              0 6px 18px -8px rgba(11,94,215,.55) !important;
}
a.cta:hover, a.btn.primary:hover, button.btn.primary:hover, .btn.primary:hover {
  box-shadow: 0 1px 0 rgba(255,255,255,.22) inset,
              0 2px 4px rgba(11,27,58,.22),
              0 12px 28px -10px rgba(11,94,215,.65) !important;
}

/* --- 20.4 Surfaces: less pillow, more panel ------------------------------ */
.card, .plan, .step, .door, .case, .doc, .ledger, .panel, .iso, details,
.lanebtn, .trust-card, .lanephoto {
  border-radius: var(--radius-lg) !important;
}
.lanephoto, .trust-card { border-radius: var(--radius-xl) !important; }

/* --- 20.5 Motion you feel ------------------------------------------------
   Reveals arrive faster and from further, so the page assembles with intent
   rather than drifting in. */
html.ff-motion .ff-reveal { transform: translateY(20px); }
html.ff-motion .ff-reveal.is-in {
  transition: opacity 420ms cubic-bezier(.16,1,.3,1),
              transform 420ms cubic-bezier(.16,1,.3,1);
}
@keyframes ff-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* The atmosphere drifts a little more, because it is the only thing on the
   page that moves on its own. */
@keyframes ff-drift {
  from { transform: translate3d(0, 0, 0) scale(1.02); }
  to   { transform: translate3d(-2%, 1.2%, 0) scale(1.06); }
}
html.ff-motion #mktBg, html.ff-motion #ff-bgvideo { animation-duration: 48s; }

/* --- 20.6 A live edge on the hero ---------------------------------------
   One hairline that catches the light across the top of the page. Costs one
   element, no script, and it is the detail that reads as "built". */
.hero { position: relative; }
.hero::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg,
    transparent, rgba(11,94,215,.35) 20%, rgba(15,118,110,.35) 55%, rgba(168,91,0,.30) 80%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  html.ff-motion #mktBg, html.ff-motion #ff-bgvideo { animation: none !important; }
}

/* ---------------------------------------------------------------------------
   21 · THE TWO LINES THAT ARE NOT MARKETING
   Every other line on this page can be cut for brevity. These two cannot: one
   says the remote lane does not move you, the other says residence is the
   destination country's law and not a service we sell. They were lost in the
   R79 rebuild and are restored as a single line each, set as a footnote so
   they read as fact rather than as a claim.
   ------------------------------------------------------------------------ */
.lane-note {
  grid-column: 1 / -1;
  margin: var(--sp-2) 0 0;
  padding-top: var(--sp-2);
  border-top: 1px solid var(--color-hair);
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--color-text-2);
}
.lane-note b { color: var(--color-text); }
.lane-note-work { border-top-color: rgba(15, 118, 110, .22); }
.lane-note-study { border-top-color: rgba(168, 91, 0, .22); }

/* ---------------------------------------------------------------------------
   22 · THE LANE PHOTOGRAPH, AT ITS PROPER SIZE
   It sat in a 300px rail: a thumbnail beside four lines of type, with a column
   of dead space under the steps because the panel stretched to the taller of
   the two. The photograph is the only proof on the page that this happens to
   real people, so it takes 42% of the panel and the type stacks against it,
   with the note and the action pinned to the bottom of the text column rather
   than floating in the middle of a gap.
   ------------------------------------------------------------------------ */
.lanepanel {
  grid-template-columns: minmax(0, 1fr) minmax(300px, 42%);
  gap: var(--sp-6);
  align-items: stretch;
}
/* Two children, not five: the photograph and one text column. Grid was
   distributing the photograph's extra height across the text rows, which put a
   200px hole between the last step and the button. A column that stacks its
   own children cannot do that. */
.lanepanel { grid-template-columns: minmax(0, 1fr) minmax(300px, 42%); }
.lanetext { display: flex; flex-direction: column; gap: var(--sp-4); align-items: start; min-width: 0; }
.lanetext .fsteps { margin: 0; }
.lanetext .lane-note { margin-top: auto; }
.lanepanel .lanephoto { grid-column: 2; grid-row: 1; height: 100%; }
.lanepanel .lanephoto img {
  height: 100%;
  width: 100%;
  min-height: 340px;
  aspect-ratio: auto;
  object-fit: cover;
  object-position: center 28%;
}
@media (max-width: 900px) {
  .lanepanel { grid-template-columns: 1fr; grid-template-rows: none; gap: var(--sp-4); }
  .lanepanel .lanephoto { grid-row: auto; grid-column: auto; }
  .lanepanel .lanephoto img { height: auto; min-height: 0; aspect-ratio: 16 / 10; }
  .lanepanel > .lane-cta, .lanepanel > .lane-note { align-self: auto; }
}

/* ---------------------------------------------------------------------------
   23 · THE ONE EXEMPTION FROM THE BOLD-INK RULE
   Section 2 paints every h1-h6, b, strong, legend, summary, th and label with
   --color-text !important. That rule earned its !important: it is what stopped
   the dark theme's pale bolds surviving on white. But it also makes it
   impossible to colour a <b> anywhere, and the lockup's three colours live in
   exactly that element. This is the only exemption, and it is narrow: the
   parts of .lane-name, nowhere else.
   ------------------------------------------------------------------------ */
.lane-name .ln-a { color: inherit !important; }
.lane-name .ln-study { color: var(--ff-lane-study, #A85B00) !important; }
.lane-name .ln-work  { color: var(--ff-lane-work,  #0F766E) !important; }
.lane-name .ln-b     { color: var(--color-text) !important; }
.lane-name sub, .lane-name sup { color: var(--color-brand) !important; opacity: 1; }

/* Bold and large, as one family: the lockup is the brand mark of each lane, so
   it is set a step up from the copy around it wherever it introduces a lane. */
.lanebtn .lane-name { font-size: clamp(17px, 1.5vw, 21px) !important; letter-spacing: -.005em; }
.lanebtn .lane-name .ln-a, .lanebtn .lane-name .ln-b { font-weight: 900; }

/* ---------------------------------------------------------------------------
   24 · THE SUCCESS RAIL
   Four fixed 4:3 cards cropped the top off a departures board and the bottom
   off a laptop screen - the exact part of each photograph carrying the message.
   Each picture now sets its own width inside a fixed height and is CONTAINED,
   so nothing is cut, and the row moves the way the destination rail does.
   ------------------------------------------------------------------------ */
.proof-rail {
  position: relative;
  overflow: hidden;
  padding: var(--sp-3) 0 var(--sp-4);
  /* The ends fade into the page instead of stopping at a hard edge. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.proof-track {
  display: flex;
  gap: var(--sp-4);
  width: max-content;
  will-change: transform;
  animation: proof-run 40s linear infinite;
}
.proof-rail:hover .proof-track,
.proof-rail:focus-within .proof-track { animation-play-state: paused; }
@keyframes proof-run { to { transform: translate3d(calc(-1 * var(--proof-w, 50%)), 0, 0); } }

.proof-card {
  margin: 0;
  flex: 0 0 auto;
  background: var(--color-surface);
  border: 1px solid var(--color-hair);
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(92,72,44,.05), 0 14px 34px -26px rgba(92,72,44,.4);
  overflow: hidden;
}
.proof-card img {
  display: block;
  height: 232px;          /* the height is fixed; the width is whatever the photo is */
  width: auto;
  max-width: 420px;
  object-fit: contain;    /* never crop: the message is inside the frame */
  background: var(--color-well);
}
.proof-card figcaption {
  padding: 9px 14px 11px;
  border-top: 1px solid var(--color-hair);
  font: var(--fw-semibold) var(--fs-sm) / 1.3 var(--font-ui);
  color: var(--color-text);
}
@media (max-width: 640px) {
  .proof-card img { height: 172px; max-width: 300px; }
  .proof-track { gap: var(--sp-3); }
}
@media (prefers-reduced-motion: reduce) {
  .proof-track { animation: none; width: auto; flex-wrap: wrap; justify-content: center; }
  .proof-rail { -webkit-mask-image: none; mask-image: none; }
}

/* The lane photograph is centred in its column rather than filling it edge to
   edge, so a portrait subject sits where the eye expects them. */
.lanepanel .lanephoto { display: grid; place-items: center; }
.lanepanel .lanephoto img { object-position: center 30%; border-radius: inherit; }

/* ===========================================================================
   25 · SILK
   The ground read as silver on a laptop: #FBFAF7 is a warm white on paper and
   a cool grey behind a cool-calibrated panel, and three flat radial washes gave
   the eye nothing to hold. This replaces them with woven bands - ivory,
   champagne, pearl blue and soft teal - drifting slowly across each other, the
   way light moves over silk.

   Three rules govern it, and every value below serves one of them:
     · the CENTRE STAYS CLEAN. A bright well sits over the middle of the page so
       type is never read against a moving band.
     · NOTHING SHOUTS. No band exceeds 9% alpha; the strongest hue is a pearl
       blue at 7%. Read the page and you should not be able to say what colour
       the background is.
     · IT COSTS ONE COMPOSITE. Two fixed pseudo-elements, transform-only
       animation, no JavaScript per frame; parallax writes one custom property
       from a rAF-throttled scroll listener.
   ========================================================================= */

:root {
  /* Warmer than the old ground by a hair - enough to stop it reading silver. */
  --silk-ground:    #FCFAF6;
  --silk-ivory:     rgba(244, 236, 222, .55);
  --silk-champagne: rgba(226, 205, 170, .34);
  --silk-pearl:     rgba(176, 199, 226, .30);
  --silk-teal:      rgba(150, 199, 193, .26);
  --silk-line:      rgba(168, 186, 208, .22);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* The public pages commit to light. These exist so a dark-preferring viewer
       still gets a deliberate ground rather than a borrowed one. */
    --silk-ground: #FCFAF6;
  }
}

/* The colour field: the ground, plus the bright well that keeps the middle clean. */
#mktBg, #ff-bgvideo {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden;
  background:
    radial-gradient(78rem 52rem at 50% 34%, rgba(255,255,255,.86) 0%, rgba(255,255,255,.55) 38%, transparent 70%),
    var(--silk-ground) !important;
  /* Parallax: the whole field drifts against the page, a fraction of the scroll. */
  transform: translate3d(0, calc(var(--silk-y, 0px) * .06), 0);
  will-change: transform;
}

/* Band one: the wide low sweep. Champagne into ivory, the warmest layer. */
#mktBg::before, #ff-bgvideo::before {
  content: '';
  position: absolute; left: -25%; right: -25%; top: -18%; bottom: -18%;
  background-repeat: no-repeat;
  background-position: 50% 68%, 50% 30%;
  background-size: 160% 78%, 150% 62%;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1600 900' preserveAspectRatio='none'%3E%3Cpath d='M0 618 C 250 556 430 704 706 660 C 982 616 1188 538 1600 612 L1600 900 L0 900 Z' fill='%23E2CDAA' fill-opacity='.34'/%3E%3Cpath d='M0 700 C 300 646 520 780 860 726 C 1200 672 1360 620 1600 690 L1600 900 L0 900 Z' fill='%23F4ECDE' fill-opacity='.55'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1600 900' preserveAspectRatio='none'%3E%3Cpath d='M0 300 C 280 232 470 372 780 318 C 1090 264 1320 196 1600 268 L1600 0 L0 0 Z' fill='%23F4ECDE' fill-opacity='.5'/%3E%3C/svg%3E");
  /* A background image ends where its box ends, and that straight edge read as a hard
     diagonal rule under the header. Both weaves are masked so they dissolve instead. */
  -webkit-mask-image: radial-gradient(128% 118% at 50% 48%, #000 42%, rgba(0,0,0,.55) 70%, transparent 92%);
          mask-image: radial-gradient(128% 118% at 50% 48%, #000 42%, rgba(0,0,0,.55) 70%, transparent 92%);
  animation: silk-a 92s ease-in-out infinite alternate;
  will-change: transform;
}

/* Band two: the cool weft. Pearl blue and soft teal, and the one drawn line. */
#mktBg::after, #ff-bgvideo::after {
  content: '';
  position: absolute; left: -25%; right: -25%; top: -18%; bottom: -18%;
  background-repeat: no-repeat;
  background-position: 50% 22%, 50% 82%, 50% 50%;
  background-size: 155% 68%, 165% 72%, 180% 100%;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1600 900' preserveAspectRatio='none'%3E%3Cpath d='M0 236 C 320 168 540 322 880 262 C 1220 202 1380 140 1600 210 L1600 0 L0 0 Z' fill='%23BACBE0' fill-opacity='.20'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1600 900' preserveAspectRatio='none'%3E%3Cpath d='M0 664 C 340 730 560 596 900 656 C 1240 716 1400 762 1600 700 L1600 900 L0 900 Z' fill='%23A6CFC8' fill-opacity='.19'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1600 900' preserveAspectRatio='none'%3E%3Cpath d='M-40 470 C 300 386 520 552 880 480 C 1240 408 1420 340 1640 412' fill='none' stroke='%23A8BAD0' stroke-opacity='.16' stroke-width='1.6'/%3E%3Cpath d='M-40 540 C 320 466 540 618 900 552 C 1260 486 1440 424 1640 490' fill='none' stroke='%23A8BAD0' stroke-opacity='.14' stroke-width='1.2'/%3E%3C/svg%3E");
  /* A background image ends where its box ends, and that straight edge read as a hard
     diagonal rule under the header. Both weaves are masked so they dissolve instead. */
  -webkit-mask-image: radial-gradient(128% 118% at 50% 48%, #000 42%, rgba(0,0,0,.55) 70%, transparent 92%);
          mask-image: radial-gradient(128% 118% at 50% 48%, #000 42%, rgba(0,0,0,.55) 70%, transparent 92%);
  animation: silk-b 128s ease-in-out infinite alternate;
  will-change: transform;
}

/* Two speeds, two directions, both small. Silk moves; it does not travel. */
@keyframes silk-a {
  from { transform: translate3d(-2.4%, .9%, 0) scale(1.04); }
  to   { transform: translate3d( 2.4%, -.9%, 0) scale(1.09); }
}
@keyframes silk-b {
  from { transform: translate3d( 3.0%, -.7%, 0) scale(1.07); }
  to   { transform: translate3d(-3.0%,  .7%, 0) scale(1.02); }
}

/* The luminous highlight: one soft sheen crossing the weave, and the vignette
   that stops a large monitor going flat at the corners. */
#mktOverlay, #ff-bgveil {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 0%, transparent 58%, rgba(92, 72, 44, .05) 100%) !important;
  transform: translate3d(0, calc(var(--silk-y, 0px) * .11), 0);
  will-change: transform;
}
#mktOverlay::before, #ff-bgveil::before {
  content: '';
  position: absolute; inset: -30% -60%;
  background: linear-gradient(104deg, transparent 34%, rgba(255,255,255,.55) 47%, rgba(255,255,255,.72) 51%, rgba(255,255,255,.4) 56%, transparent 68%);
  animation: silk-sheen 46s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes silk-sheen {
  from { transform: translate3d(-9%, 0, 0) rotate(-1.2deg); }
  to   { transform: translate3d( 9%, 0, 0) rotate( 1.2deg); }
}

/* Somebody who asks for less motion gets the weave, still, and no parallax. */
@media (prefers-reduced-motion: reduce) {
  #mktBg, #ff-bgvideo, #mktOverlay, #ff-bgveil { transform: none !important; }
  #mktBg::before, #mktBg::after, #ff-bgvideo::before, #ff-bgvideo::after,
  #mktOverlay::before, #ff-bgveil::before { animation: none !important; }
}
/* A phone paints the whole viewport every frame; two animated full-bleed layers
   there buy nothing and cost battery. The weave stays, the motion stops. */
@media (max-width: 700px) {
  #mktBg::before, #mktBg::after, #ff-bgvideo::before, #ff-bgvideo::after { animation: none; }
  #mktOverlay::before, #ff-bgveil::before { display: none; }
  #mktBg, #ff-bgvideo, #mktOverlay, #ff-bgveil { transform: none; }
}

/* ===== PHONE FIRST SCREEN (owner, 2026-09-15, acceptance test checkpoint 1) =====
   The strip stays above the headline but slim; on a phone its chips do not open a page (the first tap was taking the
   visitor away), there is no "hover" caption, "54 countries" is said once, and a plain line under the headline says what FF is. */
.hero-plain{display:none}
@media(max-width:640px){
  .rail-top{padding-block:6px 0 !important}
  .rail-top .rail-head,.rail-top .train-note,#h-eye{display:none !important}
  .rail-top .train-track{padding-block:2px 4px !important}
  .rail-top .train-rail a{pointer-events:none}
  .hero{padding-top:var(--sp-3) !important}
  .hero .wrap{padding-top:var(--sp-2) !important}
  .hero-plain{display:block;margin:12px 0 0;font:600 17px/1.45 var(--font-ui);color:var(--color-text)}
}
/* HOMEPAGE TOP (owner, 2026-09-20): the rail sits higher, no caption under it; six promises in two calm columns, one line each, green dots */
.rail-top{padding-block:8px 0 !important}
section.hero{padding-top:6px !important}
/* QUIETER (owner, 2026-09-20). These six lines were set at up to twenty pixels in bold, which made them a second
   headline arguing with the first. They are supporting detail: what we do, read after the headline, not instead of
   it. Normal weight in the reading face, a size below the body text around them, a softer ink, and a small plain
   dot in place of the haloed badge. */
/* HELD TOGETHER, NOT SPREAD ACROSS THE PAGE. Two equal halves of the whole width pushed the second column far
   from the first, so six short lines read as two unrelated lists. The columns are only as wide as their longest
   line now, sitting side by side as one block, lined up under the headline they belong to. */
#h-lead.hero-does{display:grid;grid-template-columns:repeat(2,max-content);justify-content:start;gap:9px 34px;max-width:none;margin-top:16px;font:400 clamp(11px,1vw,12.5px)/1.45 var(--font-ui);letter-spacing:0;color:var(--color-text-2,#5b6b82)}
#h-lead.hero-does li{display:flex;align-items:center;gap:8px;min-width:0}
#h-lead.hero-does li::before{content:"";flex:0 0 8px;width:8px;height:8px;margin:0;border-radius:50%;background:#16A34A !important;background-image:none !important;box-shadow:none}
@media(max-width:900px){#h-lead.hero-does{gap:8px 22px;font-size:clamp(10.5px,2.5vw,12px)}}
/* two points a row on a phone as well (owner, 2026-09-20): the type steps down and a long line wraps under its own dot */
/* on a phone the longest line decides the width, and the pair is centred, because there is no room to line them
   up under anything and a centred block of six short lines is easier to take in than two ragged columns */
@media(max-width:560px){#h-lead.hero-does{grid-template-columns:repeat(2,max-content);justify-content:center;gap:7px 16px;margin-top:14px;font-size:clamp(10px,2.9vw,11.5px);line-height:1.35}#h-lead.hero-does li{white-space:normal;align-items:flex-start;gap:6px}#h-lead.hero-does li::before{flex:0 0 7px;width:7px;height:7px;margin-top:5px;box-shadow:none}}
