/* ============================================================
   Luxembourg For Family Office — Core Stylesheet
   Palette: Dark Navy · White · Gold · Warm Brown · leaf accents
   ============================================================ */

/* ---------- Design Tokens ---------- */
:root{
  --navy:        #0f2038;   /* structural backbone */
  --navy-deep:   #0a1728;   /* darker sections / footer */
  --navy-soft:   #1c3454;   /* hover / cards on navy */
  --gold:        #c9a34e;   /* primary accent — the brand gold */
  --gold-bright: #dcb763;   /* hover accent */
  --gold-soft:   #f3ead4;   /* pale gold wash */
  /* --gold-deep was referenced in four places across three stylesheets and
     defined in none of them: the library's category labels, the payment-strip
     icons, and the top rules on the Knowledge-Hub and event cards. An unknown
     custom property with no fallback is invalid at computed-value time, so the
     labels fell back to inherited colour and — worse — the two gradients using
     it dropped their ENTIRE background declaration, rendering as bare 4px
     strips of nothing. Defined here as the shadow side of the gold, one step
     toward the trunk brown. */
  --gold-deep:   #a07c33;   /* engraved gold — darker end of the accent */
  --brown:       #7a5238;   /* secondary accent, from logo trunk */
  --brown-soft:  #a9805f;
  --cream:       #f8f5ef;   /* warm off-white — alternating sections */
  --white:       #ffffff;

  /* ── The ground — a white page, navy passages ─────────────────────────
     The site returns to its printed-prospectus footing: paper-white by
     default, with navy reserved for the deliberate passages (the header, the
     hero, the footer, the occasional standing band) so those read as engraved
     plates set INTO the page rather than one dark field the whole page floats
     on. The white margins between navy sections are intentional — keep them
     clean.

     Surfaces here are real, opaque tiles: a card is paper laid on paper,
     lifted by a warm hairline and a soft contact shadow, not a translucent
     wash. Text is dark ink by default; anything sitting on a navy passage
     re-lights its own type through --ink-navy. */
  --bg:          #ffffff;   /* the page — paper white */
  --bg-alt:      #f8f5ef;   /* cream — alternating passage */
  --bg-deep:     #0c1e3d;   /* deep navy — footer plate */
  --dark:        #0f2038;   /* navy field — hero, focus rings */
  --surface:        #ffffff;   /* cards, panels */
  --surface-2:      #faf8f2;   /* quieter fills, wells */
  --surface-raised: #ffffff;   /* menus: opaque, for reading */

  --ink:         #1b2430;   /* body text on paper */
  --ink-soft:    #55627a;   /* secondary text */
  --line:        #e7dfcd;   /* warm hairline on light — firm, not fuzzy */
  --line-soft:   #f0e9da;   /* quieter hairline */
  --line-navy:   rgba(255,255,255,.18);   /* hairline on navy passages */
  --ink-navy:      #eef3fb;               /* text on navy passages */
  --ink-navy-soft: rgba(228,236,248,.74); /* secondary text on navy */

  /* leaf palette — used sparingly */
  --leaf-red:    #c0392b;
  --leaf-orange: #d97b34;
  --leaf-amber:  #d9a441;
  --leaf-green:  #6ba04a;
  --leaf-blue:   #4a9dc0;
  --leaf-sky:    #a9d2e0;

  /* ── Depth ───────────────────────────────────────────────────────────────
     The old scale was single-layer above the smallest step: --shadow-md was
     one 14px blur, --shadow-lg one 32px blur. A single blur cannot describe a
     lit object. Real elevation needs two shadows at once — a tight, relatively
     dark CONTACT shadow that says where the object touches, and a wide, soft
     AMBIENT shadow that says how far it is from the surface. With only the
     ambient term, everything looked like a sticker on a page; that is what
     "lacks depth" describes.

     All five steps are cast in the navy ink (10,23,40) rather than neutral
     black, so the shadow belongs to this palette instead of greying it. */
  --shadow-xs: 0 1px 1px rgba(10,23,40,.05), 0 1px 3px rgba(10,23,40,.05);
  --shadow-sm: 0 1px 2px rgba(10,23,40,.06), 0 2px 7px rgba(10,23,40,.07);
  --shadow-md: 0 2px 4px rgba(10,23,40,.07), 0 8px 20px rgba(10,23,40,.10);
  --shadow-lg: 0 4px 9px rgba(10,23,40,.08), 0 18px 44px rgba(10,23,40,.15);
  --shadow-xl: 0 8px 18px rgba(10,23,40,.09), 0 34px 74px rgba(10,23,40,.20);

  /* The other half of depth, and the half that was missing entirely: an edge
     catches light on its top face and is darker underneath. These two inset
     hairlines give a raised surface a lit top edge — one tuned for light
     surfaces, one for navy — and --inset-well does the inverse for controls
     that should read as RECESSED. Buttons come toward you, fields sink in;
     without that opposition every control sits on the same plane. */
  --edge-light: inset 0 1px 0 rgba(255,255,255,.6);
  --edge-dark:  inset 0 1px 0 rgba(255,255,255,.10);
  --inset-well: inset 0 1px 2px rgba(10,23,40,.09), inset 0 0 0 1px rgba(10,23,40,.03);

  --radius-sm: 3px;
  --radius:  6px;
  --radius-lg: 10px;
  --radius-xl: 16px;

  /* ── The hairline ─────────────────────────────────────────────────────────
     Every engraved edge on this site — buttons, the header access element,
     country plates, tier cards — draws itself with this one value instead of
     hard-coding 1px. On a standard display it is one device pixel. On any
     panel that can resolve better than that it drops to half a pixel, and the
     edge stops reading as a drawn box and starts reading as an engraved rule.
     That half-pixel is the entire difference between a template outline and a
     printed one, and it costs two lines to have. */
  --hair: 1px;
  --maxw: 1340px;
  --pad: clamp(20px, 5vw, 64px);

  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* The MENU face, and only the menu — see the note above .nav-link. Kept as
     its own token so the row can be set independently of the body face
     without either one dragging the other around. */
  --menu: "Poppins", "Inter", -apple-system, BlinkMacSystemFont, sans-serif;

  --ease: cubic-bezier(.4,0,.2,1);
  /* One decisive curve for the interactive layer: fast departure, long settle.
     Everything that expands, folds or lifts uses it, so the chrome moves with a
     single hand rather than four different ones. */
  --ease-lux: cubic-bezier(.22,1,.36,1);
}
@media (min-resolution:1.5dppx){ :root{ --hair:.5px } }

/* =========================================================
   THE DRIFTING PIECE — the canopy's own box
   ---------------------------------------------------------
   js/leaf-fall.js builds every drifting piece as <span class="lffo-leaf">,
   sets --s (its own size, one square side) and --lc (its fill, matched to
   the SVG path so a future border or shadow keyed to currentColor can never
   drift from the blob itself), then positions it with inline `left` and
   `top` — its HOME point, which it then wanders around. Both of those do
   nothing without `position` declared somewhere — this is that somewhere,
   and the ONLY place it is declared. Miss it and every piece falls back into
   normal document flow: sixty unsized, unpositioned spans stack into one
   another, and because a bare <svg> with only a viewBox rasterises at the UA
   default of 300×150px, the whole field collapses into one oversized shape
   instead of sixty small ones — which is the exact defect this rule exists
   to prevent.

   No blur is set here. Every piece breathes between sharp and soft as it
   fades — see the `filter` keyframes in js/leaf-fall.js — so a blur written
   here would only ever be overridden the instant the animation starts; it
   belongs entirely to the loop, not to this box.

   The home hero canopy, the president band and every interior page hero
   share this one box; it lives here rather than in css/home.css because the
   interior pages never load that file.
   ========================================================= */
.lffo-leaf{
  position:absolute;top:0;left:0;
  width:var(--s);height:var(--s);
  pointer-events:none;
  will-change:transform,opacity,filter;
  transform-origin:50% 50%;
}
.lffo-leaf svg{display:block;width:100%;height:100%;overflow:visible}

/* =========================================================
   HERO CANOPY — section 1's background leaves (js/hero-canopy.js)
   ---------------------------------------------------------
   A different piece from `.lffo-leaf` above and kept separate on purpose.
   `.lffo-leaf` is a DRAWN leaf — an SVG with a graded blade, an outline and
   its veins — drifting around a fixed point; it serves the president band.
   `.canopy-leaf` is a FLAT leaf: one solid fill and a border-radius, falling
   through the hero. Two effects, two boxes, no shared mode flag to get wrong.

   Both containers live here rather than in home.css because the interior
   pages never load that file, and both are empty positioned divs: the gust
   and the leaves animate transforms, and a transform on an element that
   holds the H1 would put the heading on its own paint layer sized to its
   border box — which is what used to clip the descenders.

   No `will-change`. It pinned a compositor layer per leaf for the life of
   the page, including while the hero was scrolled away. The browser promotes
   an element with a running transform/opacity animation by itself and
   releases the layer when that animation pauses, which is what the animation
   budget in js/main.js relies on.
   ========================================================= */
.hero-canopy{position:absolute;inset:0;pointer-events:none;z-index:1}
.ph-canopy{position:absolute;inset:0;pointer-events:none;z-index:0}
/* The watermark layer sits ABOVE the hero copy (.hero-inner is z-index:2) so
   its pieces cross the ghosted LUXEMBOURG lettering instead of passing
   behind it. It is safe there only because of how faint its leaves are —
   see .canopy-leaf--mark below and the note in js/hero-canopy.js. It must
   stay pointer-events:none or it would swallow clicks on the CTAs. */
.hero-canopy-front{position:absolute;inset:0;pointer-events:none;z-index:3}
.canopy-leaf{
  position:absolute;top:0;left:0;
  width:var(--s,16px);height:var(--s,16px);
  background:var(--lc,var(--gold));
  border-radius:var(--br,50% 0 50% 50%);
  filter:blur(var(--bl,0px));
  opacity:0;
  pointer-events:none;
  transform-origin:50% 50%;
}
/* A piece in the watermark layer. `screen` is what keeps it a watermark: on
   the hero's dark navy it can only ever LIGHTEN what is under it, so where
   one crosses the gold lettering the letter reads through it as a tint
   rather than being covered. With normal blending the same piece would sit
   on top of the type as a solid patch, however low its opacity. Overlaps
   between two of them accumulate softly for the same reason, instead of
   stacking into an opaque edge. */
.canopy-leaf--mark{mix-blend-mode:screen}
/* Phone only: a warm bloom behind the canopy — light coming through leaves.
   It exists only where the field is dense enough at the top of the hero for
   there to be anything for the light to come through. */
@media (max-width:720px){
  .hero-canopy::after{
    content:"";position:absolute;top:-14%;right:-22%;
    width:88vw;height:88vw;border-radius:50%;pointer-events:none;
    background:radial-gradient(circle at 62% 34%,
      rgba(217,164,65,.20) 0%,
      rgba(201,163,78,.13) 34%,
      rgba(122,82,56,.07) 58%,
      transparent 76%);
    filter:blur(6px);
    animation:canopyGlow 11s ease-in-out infinite;
  }
  @keyframes canopyGlow{
    0%,100%{opacity:.82;transform:scale(1)}
    50%    {opacity:1;transform:scale(1.06)}
  }
}
@media (prefers-reduced-motion:reduce){
  /* the generator never runs under reduced motion, so there are no leaves
     to hide — only the glow needs stilling */
  .hero-canopy::after{animation:none}
}

/* =========================================================
   VIEW TRANSITIONS — the site behaves as one instrument
   ---------------------------------------------------------
   Eight static pages that each reloaded from white now cross-fade into one
   another, and the header and footer are declared as the SAME element across
   documents, so they hold still while the page beneath them changes. Without
   the names the whole viewport would fade as one block and the chrome would
   blink; with them the navigation reads as a panel swap inside a fixed frame.
   Progressive enhancement: browsers without the API simply navigate as before.
   ========================================================= */
@view-transition{navigation:auto}
::view-transition-old(root),
::view-transition-new(root){
  animation-duration:.42s;
  animation-timing-function:cubic-bezier(.22,1,.36,1);
}
/* The morphing chrome. mix-blend-mode:normal stops the two snapshots from
   double-darkening the navy while they overlap. */
.site-header{view-transition-name:lffo-header}
.site-footer{view-transition-name:lffo-footer}
::view-transition-group(lffo-header),
::view-transition-group(lffo-footer){animation-duration:.42s}
::view-transition-old(lffo-header),
::view-transition-new(lffo-header),
::view-transition-old(lffo-footer),
::view-transition-new(lffo-footer){mix-blend-mode:normal;height:100%}
@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*){animation:none !important}
}

/* ---------- LFFO Wordmark ----------
   The footer wordmark is drawn from OUTLINE PATHS generated from this face, so
   the logo itself needs no font at run time and never waits on one.

   The ITALIC is now live type as well: version 2.000 of LFFO Wordmark Italic
   carries 170 codepoints against version 1's 94 — the whole Latin-1 accent
   range, ¡ ¿ « » and the Œ/Ÿ pair — which is the difference between a face
   that can only set an English logo and one that can set a page heading in
   French, German and Spanish without a single glyph falling back to a
   different typeface mid-word. Every character in every H1 on this site, in
   all four languages, was checked against its cmap before it was adopted.

   It is used for interior page H1s and nothing else. Below about 18px the
   face goes spindly — it is a high-contrast italic and its hairlines thin out
   — so it is deliberately kept away from buttons, the header plate and any
   small control. The roman is still declared but unreferenced. */
/* ?v=3 is not decoration. The face has been corrected three times and the file
   name never changed, so a browser that had already cached lffo-wordmark-italic
   .woff kept serving the OLD outlines and none of the corrections appeared —
   the reader sees the letters they saw last week and reasonably reports that
   nothing was fixed. The version token makes each corrected face a different
   URL, so a stale cache cannot mask a fix. Bump it whenever the fonts are
   rebuilt. */
@font-face{
  font-family:"LFFO Wordmark";
  src:url("../fonts/lffo-display-roman.woff?v=3") format("woff"),
      url("../fonts/lffo-display-roman.ttf?v=3") format("truetype");
  font-style:normal;font-weight:400;font-display:swap;
}
@font-face{
  font-family:"LFFO Wordmark";
  src:url("../fonts/lffo-wordmark-italic.woff?v=3") format("woff"),
      url("../fonts/lffo-wordmark-italic.ttf?v=3") format("truetype");
  font-style:italic;font-weight:400;font-display:swap;
}

/* ---------- Reset ---------- */
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  font-family:var(--sans);
  color:var(--ink);
  /* The page is paper. A single, barely-there warm wash at the very top keeps
     pure #fff from feeling clinical where the white body meets the navy header,
     then resolves to clean white for the rest of the document. No fixed
     immersive field any more — navy is a passage, not the ground. */
  background:
    radial-gradient(120% 46% at 82% -8%,rgba(201,163,78,.05),transparent 60%),
    var(--bg);
  line-height:1.6;
  font-size:16px;
  overflow-x:hidden;
}
/* Content sections carry no fill of their own, so the white page shows through;
   the deliberate navy passages set their own dark ground via .page-hero /
   .lit-navy below. A cream band (.section-soft) marks an alternating passage
   without a hard colour edge. */
.section,.intro-band,
.season-spring,.season-summer,.season-autumn{background:transparent}
.section-soft{
  background:var(--bg-alt);
  border-block:1px solid var(--line-soft);
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font-family:inherit;cursor:pointer;border:none;background:none}
ul{list-style:none}

.container{max-width:var(--maxw);margin-inline:auto;padding-inline:var(--pad)}

/* ---------- Typography ---------- */
h1,h2,h3,h4{font-family:var(--serif);font-weight:600;line-height:1.12;color:var(--navy);letter-spacing:-.01em}
h1{font-size:clamp(2.4rem,5.2vw,4.1rem)}
h2{font-size:clamp(1.9rem,3.8vw,2.9rem)}
h3{font-size:clamp(1.3rem,2.2vw,1.7rem)}
p{color:var(--ink-soft)}

.eyebrow{
  font-family:var(--sans);
  font-size:.72rem;
  font-weight:600;
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--gold);
  display:inline-flex;
  align-items:center;
  gap:.6em;
}
.eyebrow::before{
  content:"";width:26px;height:1px;background:var(--gold);display:inline-block;
}
.eyebrow.center::before{display:none}

/* ── Render containment ──────────────────────────────────────────────────
   The home page is nine full sections tall and carries a lot of ornament:
   forty-odd absolutely-positioned leaves, an SVG map with twenty-four spokes,
   a tree mark drawn from thirteen paths. All of it was laid out and painted on
   first load, including the seven sections nobody had scrolled to yet.

   content-visibility:auto lets the browser skip layout and paint for a section
   until it is close to the viewport. contain-intrinsic-size is the essential
   half of the pair: it supplies a placeholder height so the scrollbar is
   accurate and skipped sections do not collapse to nothing and make the page
   jump as they are rendered. 900px is a deliberate over-estimate of a typical
   section — too small causes visible settling on fast scrolls, too large only
   costs a slightly generous scrollbar.

   Three exclusions, all deliberate. .lib-section and .has-sticky hold the two
   filter consoles, which are position:sticky — content-visibility implies
   paint containment, and a sticky element inside a paint-contained ancestor is
   clipped to it, so the console would vanish at the exact moment it pinned.
   .hero is the one section always on screen at load, so containing it would
   add work rather than remove it. Any future section that pins something
   should carry .has-sticky for the same reason.

   The `auto` keyword on contain-intrinsic-size matters: after a section has
   been rendered once the browser remembers its real height and uses that
   instead of the 900px guess, so the estimate only ever affects the very
   first pass. */
.section{padding-block:clamp(56px,9vw,110px)}
.section:not(.hero):not(.lib-section):not(.has-sticky){
  content-visibility:auto;
  contain-intrinsic-size:auto 900px;
}
.section-head{max-width:640px;margin-bottom:clamp(32px,5vw,56px)}
.section-head.center{margin-inline:auto;text-align:center}
.section-head p{margin-top:16px;font-size:1.08rem}
/* The eyebrow is a <p>, so .section-head p was quietly overriding .eyebrow's
   own .72rem and setting it to 1.08rem — 17px of letterspaced uppercase. That
   is an accident of specificity, not a decision, and on a phone it made the
   label above each section heading ("EUROPEAN PRESENCE") read louder than the
   heading itself while eating two lines of a 350px column. The desktop size is
   left alone; below 720px the eyebrow takes back its own size and loses a
   little tracking so it sits on one line. */
@media (max-width:720px){
  .section-head p.eyebrow,.eyebrow{font-size:.72rem;letter-spacing:.15em}
}

/* ═══════════════════════════════════════════════════════════════════════
   BUTTONS — quieter, smaller, and gold only where gold means something
   ═══════════════════════════════════════════════════════════════════════
   The previous set was too big, too bold and too gold: 700-weight, .16em
   tracked, heavy padding, and a solid gold slab used for every primary
   action on every page. Gold used that often stops reading as an accent and
   starts reading as a colour scheme — and a page with four gold slabs on it
   has no primary action at all.

   The rules now:

   · SMALLER. .72rem, tighter padding, 600 weight. A button is a destination,
     not a headline; it should be the quietest confident thing on the page.
   · ALMOST NO FILL. The default is a hairline and a label. The control
     announces itself by its edge and its spacing, the way a printed card
     does, and only fills on approach — and even then to a restrained tone,
     not to full gold.
   · ONE ACCENT. Gold is reserved for the hairline, the arrow, and the fill
     that arrives on hover. Nothing sits in solid gold at rest except the
     single membership action, and even that is a softer gold than before.
   · THE SHINE IS MEMBERSHIP ONLY. It marks the one thing the association is
     actually asking of a visitor — joining. It is applied through .btn-member
     and appears nowhere else on the site.

   Everything is square (2px), because this identity is engraved, not
   rounded, and the corner is the cheapest place to say so. */
/* ═══════════════════════════════════════════════════════════════════════
   BUTTONS — engraved, square, and STILL (the box never resizes or lifts).
   Feedback is colour, a "ledge" of light under the edge, and — on the one
   membership action — engraver's signet marks plus a slow looping gold shine.
   Three tiers, drawn from the design-lab marks:
     · Primary   .btn-gold (+.btn-member): the single solid-gold action, joining
     · Secondary .btn-navy / .btn-ghost-light: engraved outline + ledge glow
     · Tertiary  .link-cta text links (below) — not buttons at all
   Everything is square (radius 0); no pills anywhere.
   ═══════════════════════════════════════════════════════════════════════ */
/* ── Editorial button base ───────────────────────────────────────────────────
   Sentence-case labels set a touch smaller with open, considered tracking; a
   hairline 1px edge; generous, balanced inner spacing; and the icon carried as
   a quiet companion to the label (lighter, smaller, its own subtle step on
   hover) rather than a loud chevron. Everything eases on one soft curve. */
.btn{
  position:relative;overflow:hidden;
  display:inline-flex;align-items:center;justify-content:center;gap:.6em;
  padding:.9em 1.7em;
  border-radius:0;
  border:var(--hair) solid transparent;
  font-family:var(--sans);
  font-size:.82rem;font-weight:600;letter-spacing:.045em;line-height:1.1;
  white-space:nowrap;cursor:pointer;
  transition:color .34s var(--ease-lux),background-color .34s var(--ease-lux),
             border-color .34s var(--ease-lux),box-shadow .38s var(--ease-lux);
}
/* Tactile — the press, not the hover.
   Hover on this site is a slow, quiet arrival: a third of a second on the
   luxury curve, so approaching a control never snaps. The PRESS is the
   opposite and that contrast is the whole tactility: everything collapses to
   90ms, the face dips a shade and the edge tightens, then releases back on
   the slow curve when the finger leaves. Nothing scales, nothing lifts,
   nothing reflows — the button answers under your finger without moving,
   the way a key on a good instrument does. */
.btn:active{transition-duration:.09s}
.btn::before{content:none}
.btn > span,.btn > i{position:relative;z-index:3}
/* The icon reads as a mark beside the label, not competing with it. */
.btn > i{font-size:.94em;opacity:.72;transition:transform .34s var(--ease-lux),opacity .3s var(--ease)}
.btn:hover > i,.btn:focus-visible > i{transform:translateX(2px);opacity:1}
.btn:active > i{transform:translateX(1px)}
.btn:focus-visible{outline:none;box-shadow:0 0 0 1px var(--bg),0 0 0 2px var(--gold-bright)}
.btn-lg{padding:1em 2.1em;font-size:.86rem}

/* ── The single membership CTA ───────────────────────────────────────────────
   One style for the association's primary action wherever it appears — the
   hero, the membership teasers, the join-the-association band and the footer.
   It carries slightly more weight and breathing room than a normal button and
   takes a refined lift on hover that nothing else does, so the membership call
   always reads as the lead action in any hierarchy. */
.btn-member{letter-spacing:.045em;
  transition:color .26s var(--ease),background-color .26s var(--ease),
             border-color .26s var(--ease),box-shadow .32s var(--ease-lux)}
.btn-member.btn-lg{padding:1.02em 2.25em;font-size:.95rem}
/* The lift is gone. It was the one control on the site that moved when you
   pointed at it, which read as a web button rather than an engraved plate,
   and it fought the rule every other mark here obeys. The membership action
   still leads the hierarchy — through weight, spacing and the halo — while
   holding perfectly still. */

/* Primary — the single solid-gold action (membership). Halo Glow (lab 02),
   refined: on approach a soft, close, low-contrast gold bloom rises around the
   edge — no hard ring, nothing diffuse or noisy. */
.btn-gold{
  color:#241a09;background-color:var(--gold);border-color:var(--gold-deep);
  box-shadow:0 1px 2px rgba(40,30,8,.09),0 4px 12px rgba(201,163,78,.12);
}
/* The halo is close, low-contrast and finite: it rises to this and stops. */
.btn-gold:hover,.btn-gold:focus-visible{
  background-color:var(--gold-bright);border-color:var(--gold-bright);
  box-shadow:0 1px 3px rgba(40,30,8,.10),0 0 15px rgba(201,163,78,.19);
}
.btn-gold:active{
  background-color:var(--gold);
  box-shadow:inset 0 1px 3px rgba(90,62,24,.22),0 1px 2px rgba(40,30,8,.14);
}

/* Secondary on light — engraved navy outline, empty inside. A single hairline
   ledge settles under it on approach; no diffuse bloom. */
.btn-navy{
  color:var(--navy);background-color:transparent;border-color:rgba(15,32,56,.42);
}
.btn-navy:hover,.btn-navy:focus-visible{color:var(--navy);border-color:rgba(15,32,56,.9);box-shadow:0 var(--hair) 0 var(--navy)}
.btn-navy:active{border-color:var(--navy);box-shadow:inset 0 1px 2px rgba(15,32,56,.15)}

/* Secondary on navy passages — light hairline outline; on approach the edge
   warms to gold and a single fine ledge settles under it. No diffuse glow. */
.btn-ghost-light{
  color:#fff;background-color:transparent;border-color:rgba(255,255,255,.32);
}
.btn-ghost-light:hover,.btn-ghost-light:focus-visible{color:#fff;border-color:var(--gold-bright);box-shadow:0 var(--hair) 0 rgba(201,163,78,.66)}
.btn-ghost-light:active{border-color:var(--gold);box-shadow:inset 0 1px 2px rgba(0,0,0,.16)}

/* Quiet outline on light — the softest button. */
.btn-ghost{
  color:var(--ink-soft);background-color:transparent;border-color:var(--line);
}
.btn-ghost:hover,.btn-ghost:focus-visible{color:var(--navy);border-color:var(--gold);box-shadow:0 var(--hair) 0 rgba(201,163,78,.5)}
.btn-ghost:active{box-shadow:inset 0 1px 2px rgba(10,23,40,.1)}

/* Membership shine — thinner, slower, quieter.
   There is no loop and there never was a ring: a single narrow band of light
   crosses the face once on approach and does not come back until you leave
   and return. It used to be a 55%-wide wash at .34 alpha, which on a gold
   ground read as a flash across half the button. It is now a 26% band at .2,
   travelling on the luxury curve over a full second — you register that the
   surface caught the light, not that something animated. */
.btn-gold > .btn-shine{display:none}
.btn-gold::after{
  content:"";position:absolute;top:-25%;bottom:-25%;left:0;width:26%;z-index:1;pointer-events:none;
  background:linear-gradient(100deg,
    rgba(255,253,246,0) 0%,rgba(255,253,246,.20) 50%,rgba(255,253,246,0) 100%);
  transform:translateX(-220%) skewX(-11deg);opacity:0;
  transition:transform 1.02s var(--ease-lux),opacity .42s var(--ease);
}
.btn-gold:hover::after,
.btn-gold:focus-visible::after{transform:translateX(560%) skewX(-11deg);opacity:1}
@media (prefers-reduced-motion:reduce){
  .btn-gold::after{display:none}
}

/* Underline Sweep (lab mark 08) — a hairline sweeps in under the label on
   approach, left to right; no box, no lift. Used for the hero's quiet secondary
   action ("Discover LFFO"). */
.btn-sweep{background:transparent;border-color:transparent}
.btn-sweep > span{position:relative;display:inline-block}
.btn-sweep > span::after{
  content:"";position:absolute;left:0;bottom:-5px;height:1px;width:100%;background:currentColor;
  opacity:.55;transform:scaleX(0);transform-origin:left;transition:transform .4s var(--ease-lux);
}
.btn-sweep:hover > span::after,.btn-sweep:focus-visible > span::after{transform:scaleX(1)}
.btn-sweep:active > span::after{opacity:.9}
.btn-sweep.on-dark{color:#fff}
.btn-sweep.on-dark:hover,.btn-sweep.on-dark:focus-visible{color:var(--gold-bright)}

/* ── The lab interaction set — SIX marks, one per role ───────────────────────
   The vocabulary is closed. These six are the whole set the site is allowed to
   speak, drawn from lffo-button-menu-lab_5 and refined rather than copied
   across. Nothing here loops, nothing is diffuse, and nothing resizes, lifts
   or translates the box it is attached to — every one of them answers with
   light, an edge, or one small mark of its own. One button carries one mark:
   two on the same element is a doubling, not a refinement.

     · 01 Ledge Glow      .btn-ledge  a hairline of light settles under the edge
                                      — the plain navy actions and the wizard's
                                        Next
     · 02 Halo Glow       .btn-gold   the primary gold actions, incl. the member
                                        login submit (rule above)
     · 03 Ember Border    .btn-ember  the edge itself ignites, tight and hot —
                                        outlined buttons, the header access
                                        plate and the Library filter toggle
     · 04 Inner Glow      .btn-inner  light switches on behind the label — the
                                        document actions: read the paper, browse
                                        the full library
     · 05 Corner Spark    .btn-spark  two quiet points brighten — the header
                                        plate, the country plates, the tier
                                        guide
     · 08 Underline Sweep .btn-sweep  a rule fills in under the label (above) —
                                        tertiary text actions

   Removed from the site entirely, along with the rules that drew them: Signet
   Marks (06), Weighted Type (07), TREE RING (09), Page Fold (10), Ledger Tick
   (11) and Facet (12). Tree Ring held the three document actions — read the
   paper and the two library links — and they have moved to Inner Glow, which is
   the better reading anyway: a light coming on behind the label is what opening
   a document feels like, where a ring opening from the centre was a second
   circular motif competing with the mark's own tree. Signet's header access
   element moved to Ember Border + Corner Spark. */

/* 01 Ledge Glow — a line the exact colour of the border waits under the
   button, invisible at rest, and glows in on approach. Nothing presses. */
/* The ledge is LIGHT, so it is drawn in the identity's light colour whatever
   the button is. It used to be navy under a navy-outlined button, which on a
   white page reads as a drop shadow rather than as something switching on —
   the mark is called Ledge Glow, and a navy line under a white box does not
   glow. Gold under every variant also keeps the six marks speaking one
   language instead of one language per button colour. */
.btn-ledge{--ledge:var(--gold)}
.btn-navy.btn-ledge{--ledge:var(--gold-deep)}
.btn-ghost-light.btn-ledge,.btn-ghost.btn-ledge{--ledge:var(--gold-deep)}
.btn-ledge:hover,.btn-ledge:focus-visible{box-shadow:0 var(--hair) 0 var(--ledge)}
.btn-ledge:active{box-shadow:0 var(--hair) 0 var(--ledge),inset 0 1px 2px rgba(10,23,40,.13)}

/* 03 Ember Border — the border line itself ignites: a tight, hot glow held
   right along the edge, nothing diffuse and nothing outside it. */
.btn-ember:hover,.btn-ember:focus-visible{
  border-color:var(--gold);
  box-shadow:0 0 0 var(--hair) var(--gold),0 0 6px rgba(201,163,78,.4);
}
.btn-ember:active{box-shadow:0 0 0 var(--hair) var(--gold),0 0 3px rgba(201,163,78,.62)}

/* 04 Inner Glow — a soft light switches on behind the label, from the centre. */
.btn-inner::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;opacity:0;
  background:radial-gradient(ellipse at center,rgba(255,251,240,.26) 0%,rgba(255,251,240,0) 72%);
  transition:opacity .42s var(--ease-lux)}
.btn-navy.btn-inner::before,.btn-ghost-light.btn-inner::before,.btn-ghost.btn-inner::before{
  background:radial-gradient(ellipse at center,rgba(201,163,78,.17) 0%,rgba(201,163,78,0) 72%)}
.btn-inner:hover::before,.btn-inner:focus-visible::before{opacity:1}

/* 05 Corner Spark — two quiet points at opposite corners brighten on approach;
   only their brightness changes, nothing about them ever moves. */
.btn-spark::before,.btn-spark::after{content:"";position:absolute;width:2px;height:2px;border-radius:50%;
  background:var(--gold-deep);opacity:.28;pointer-events:none;z-index:4;
  transition:opacity .32s var(--ease-lux),box-shadow .32s var(--ease-lux)}
.btn-navy.btn-spark::before,.btn-navy.btn-spark::after,
.btn-ghost-light.btn-spark::before,.btn-ghost-light.btn-spark::after{background:rgba(255,255,255,.82)}
.btn-spark::before{top:6px;left:6px}
.btn-spark::after{bottom:6px;right:6px}
.btn-spark:hover::before,.btn-spark:hover::after,
.btn-spark:focus-visible::before,.btn-spark:focus-visible::after{opacity:1;box-shadow:0 0 5px currentColor}

/* Registered angle for the travelling category glow on cards (library +
   knowledge). Animating a typed custom property lets a conic highlight loop
   smoothly around a masked border ring without repainting geometry. */
@property --lffo-glow{syntax:'<angle>';initial-value:0deg;inherits:false}
@keyframes lffoTravel{to{--lffo-glow:360deg}}

/* Join mark — the real LFFO logo, carried in a small navy badge so the
   colourful tree reads exactly as it does in the header. The badge makes the
   primary action a logo-and-label lockup, not a line of text with a smudge. */
.btn-join{display:inline-flex;align-items:center;gap:.6em;justify-content:center;padding-left:.7em}
.btn-join .join-mark{
  position:relative;z-index:2;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  width:1.75em;height:1.75em;background:var(--navy);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);
}
.btn-join .join-mark .join-tree{width:1.15em;height:auto;display:block}
.btn-join > span{position:relative;z-index:2}

/* ── Tertiary — text link, not a button. Underline sweeps in on approach and
   the arrow steps forward; no box, no chrome. Used for every non-essential
   action so buttons stay reserved for what matters. */
.link-cta{
  display:inline-flex;align-items:center;gap:.45em;
  font-family:var(--sans);font-size:.9rem;font-weight:600;letter-spacing:.015em;
  color:var(--navy);cursor:pointer;position:relative;background:none;border:none;padding:.2em 0;
  transition:color .2s var(--ease);
}
.link-cta > span{position:relative;display:inline-block}
.link-cta > span::after{
  content:"";position:absolute;left:0;bottom:-3px;height:1px;width:100%;
  background:var(--gold);transform:scaleX(0);transform-origin:left;
  transition:transform .4s var(--ease-lux);
}
.link-cta:hover > span::after,.link-cta:focus-visible > span::after{transform:scaleX(1)}
.link-cta i{font-size:1.05em;transition:transform .3s var(--ease-lux)}
.link-cta:hover i,.link-cta:focus-visible i{transform:translateX(3px)}
.link-cta:hover,.link-cta:focus-visible{color:var(--gold-deep);outline:none}
.link-cta.on-navy{color:#fff}
.link-cta.on-navy > span::after{background:var(--gold-bright)}
.link-cta.on-navy:hover,.link-cta.on-navy:focus-visible{color:var(--gold-bright)}

/* ── Mobile filter sheet chrome (shared by Library + Knowledge Hub) ──────────
   A floating button summons the filter console back as a bottom sheet once the
   reader has scrolled past it; a dim backdrop and a grab handle dismiss it.
   These are inert on desktop, where the sticky console still rules. */
.fc-fab{
  position:fixed;right:16px;bottom:18px;z-index:190;display:none;
  align-items:center;gap:.5em;
  padding:.82em 1.2em;border:1px solid var(--gold-deep);border-radius:0;
  background:var(--gold);color:#20160a;
  font-family:var(--sans);font-weight:700;font-size:.88rem;letter-spacing:.02em;
  box-shadow:0 8px 24px rgba(40,30,8,.28),0 2px 6px rgba(40,30,8,.2);cursor:pointer;
}
.fc-fab i{font-size:1.18em}
.fc-fab .fc-fab-count{
  width:7px;height:7px;background:var(--navy);display:none;
}
.fc-fab.has-count .fc-fab-count{display:inline-block}
.fc-backdrop{
  position:fixed;inset:0;z-index:195;background:rgba(10,18,32,.5);
  opacity:0;visibility:hidden;transition:opacity .28s var(--ease),visibility .28s;
}
body.fc-sheet-open .fc-backdrop{opacity:1;visibility:visible}
.fc-sheet-handle{display:none}
body.fc-sheet-open .fc-sheet-handle{
  display:block;width:42px;height:4px;border-radius:2px;background:#d8d2c4;
  margin:2px auto 12px;cursor:pointer;
}
@keyframes fcSheetUp{from{transform:translateY(100%)}to{transform:translateY(0)}}
@media (min-width:761px){ .fc-fab,.fc-backdrop{display:none !important} }
@media (max-width:760px){
  body.fc-past .fc-fab{display:inline-flex}
  body.fc-sheet-open .fc-fab{display:none}
}

@media (prefers-reduced-motion:reduce){
  .btn,.btn i,.link-cta i,.link-cta>span::after{transition:none}
  .btn-gold > .btn-shine{display:none}
  .btn-inner::before,.btn-spark::before,.btn-spark::after,
  .btn-sweep>span::after{transition:none}
}

/* =========================================================
   HEADER / NAV
   ========================================================= */
/* ── The bar ─────────────────────────────────────────────────────────────
   SOLID. It was translucent — 46% navy over a heavy blur — on the theory that
   the hero would show through it. It does not, and cannot, for a structural
   reason: the header is position:STICKY, so it occupies its own space at the
   top of the document and the hero begins BELOW it. At rest there is nothing
   behind the bar at all except <body>, which is white. 46% navy over white
   computes to #9198a3 — nine per cent saturation, sixty per cent lightness.
   That is not a tinted navy, it is grey, and it was grey on every page before
   the reader had scrolled a single pixel.

   Nor can it be rescued by raising the alpha. This site's body is white and
   every page is mostly white content, so the moment anyone scrolls, white
   passes under the bar and greys it again — on eight of the nine pages, most
   of the time. Translucent chrome only works over content that is reliably
   dark. Here it is reliably light.

   So the bar is its own surface: a solid navy with a slight vertical fall so
   it reads as a lit object rather than a flat block, closed by a gold
   hairline. It gains a shadow and deepens a shade once the page is scrolled,
   which is the honest way to say "this is now floating above content". */
/* A softer, flatter header: a barely-there navy gradient (a few percent of
   tonal shift instead of a heavy dark ramp) so the bar reads clean and light
   and settles naturally against the hero and the page below it. */
.site-header{
  position:sticky;top:0;z-index:100;
  background:linear-gradient(180deg,#21466f 0%,#1f426a 100%);
  border-bottom:1px solid rgba(201,163,78,.14);
  transition:background .38s var(--ease-lux),border-color .38s var(--ease-lux),
             box-shadow .38s var(--ease-lux);
}
.site-header.condensed{
  background:linear-gradient(180deg,#1e4169 0%,#1c3d63 100%);
  border-bottom-color:rgba(201,163,78,.18);
  box-shadow:0 8px 24px rgba(6,14,26,.20);
}
.site-header.menu-open{
  background:linear-gradient(180deg,#1e4169 0%,#1c3d63 100%);
}
/* Condensed is tighter than it was (54px, was 58) and every property that
   moves when it engages — bar height, logo scale, link padding — now
   shares ONE duration and ONE easing (.38s var(--ease-lux)) instead of
   three slightly different ones (.4s/.42s/.46s). Nothing here settles a
   beat after everything else any more; the whole bar reads as one object
   tightening, not three. */
.nav-bar{
  display:flex;align-items:center;justify-content:space-between;
  height:74px;
  transition:height .38s var(--ease-lux);
}
.site-header.condensed .nav-bar{height:54px}

.brand{display:flex;align-items:center;gap:.6em;flex-shrink:0}
/* .brand img and .brand-text removed: the brand has been an inline SVG since
   the mark was redrawn, and neither selector matches anything in any page. */

/* ── The mark ────────────────────────────────────────────────────────────
   The name is never hidden. The previous version cropped the wordmark away on
   scroll and left the tree standing alone, which meant that for most of the
   time anyone spends on a page the association was not actually named
   anywhere in the chrome. Cheap to build, expensive to a body whose whole job
   is to be recognised. The mark now holds its full lockup at every scroll
   position; only the bar's own height eases, and the mark eases with it in
   proportion, so the two never look welded at different rates.

   The one behaviour the mark keeps is the bloom — see below. */
.brand-logo{
  height:50px;width:198px;display:block;overflow:visible;
  transform-origin:left center;
  transition:transform .38s var(--ease-lux);
}
/* Scaled, not cropped: at 0.8 the whole lockup — tree AND words — sits
   comfortably inside the 54px condensed bar, and every letter is still there
   to be read. */
.site-header.condensed .brand-logo{transform:scale(.8)}

/* ── NEW: the mark is also the way back up ───────────────────────────────
   On any page, the logo links home. But when you are ALREADY home and you
   have scrolled, that link does nothing you can see — it reloads the page you
   are on. js/main.js detects that case and turns the mark into a return: the
   page scrolls smoothly to the top and the canopy blooms as it arrives. The
   cursor and the accessible name change to match, so the control never
   promises one thing and does another. */
.brand.is-top-link{cursor:pointer}
.brand:focus-visible{outline:none;box-shadow:0 0 0 3px var(--gold-bright);border-radius:4px}

@media (prefers-reduced-motion:reduce){
  .brand-logo{transition:none}
  .site-header.condensed .brand-logo{transform:none}
  .nav-bar,.site-header{transition:none}
  .site-header.condensed .nav-bar{height:74px}
}
/* The header lockup is the same wordmark as the footer lockup, and until now
   it was not: the footer is outline paths struck from LFFO Wordmark Italic
   while this was live text set in Cormorant Garamond. Two different typefaces
   for one wordmark, one at the top of every page and one at the bottom. It is
   now the real face, matched to the footer's own italic. */
/* ── The header wordmark is OUTLINE PATHS, not type ──────────────────────────
   It was two <text> elements in LFFO Wordmark Italic at 20px and 15.6px — the
   smallest this face is set anywhere on the site. It is a high-contrast italic,
   so at 20px its hairlines land on about one device pixel and the rasteriser
   has to decide, stem by stem, whether to paint each one, drop it, or smear it
   over two pixels. That decision comes out differently for every letter, which
   is what made "Luxembourg" read as noisy: its u, m and b are dense verticals
   sitting just under the grid.

   As outlines the letterforms are geometry. The browser's vector rasteriser
   scales them with full anti-aliasing and makes no hinting decisions at all, so
   the edges stay clean at any size and at any zoom, they do not shift when the
   header condenses on scroll, and the lockup no longer waits on a webfont —
   no swap flash on the logo. Regenerate with fonts/make_nav_logo.py if the
   face or the lockup ever changes. */
.brand-word .bw-lux,.brand-word .bw-sub{
  /* Optical weight compensation, which is only possible now the wordmark is
     geometry. This face is a high-contrast condensed italic: at the 20px the
     header sets it, its hairlines are thinner than one device pixel, so they
     came and went from stroke to stroke and the word read as broken up rather
     than drawn. Stroking each outline in its own fill colour thickens every
     contour by the same fraction of a unit, which puts body back into the
     hairlines without touching the stems' shape, the spacing or the lockup's
     width. paint-order keeps the stroke under the fill so joins stay crisp.
     0.34 units at a 20px cap height is about a fifth of a pixel — invisible as
     weight, decisive as legibility. */
  stroke:currentColor;stroke-width:.34;stroke-linejoin:round;paint-order:stroke fill;
  vector-effect:non-scaling-stroke;
}
.brand-word .bw-lux{fill:#fff;color:#fff}
/* "For Family Office" enlarged for legibility — it was reading as a caption
   rather than as half the wordmark. Letter-spacing eased slightly so the wider
   type still clears the 198-unit viewBox. */
.brand-word .bw-sub{fill:var(--gold-bright);color:var(--gold-bright);stroke-width:.28}
/* ── The bloom ───────────────────────────────────────────────────────────
   The mark does exactly one thing, and only when asked. It used to do three:
   a hover bloom, a separate bloom that fired on every page load on phones,
   and an overshoot at 70% that made each leaf pop past its own size before
   settling. A logo that animates itself on arrival is a logo asking for
   attention it has not earned, and next to a wordmark that is already stating
   the name in full it was pure noise. Both are gone.

   What is left: a single smooth unfurl on hover, root to crown. No overshoot,
   no rotation snap — a monotonic ease-out, so every leaf approaches its
   resting size and stops there. --i runs crown(0) → root(11) in markup order,
   so it is inverted here: leaves nearest the trunk settle first and the bloom
   reads as growth rising through the canopy. */
.brand-tree .lf{transform-box:fill-box;transform-origin:center}
.brand-tree .tk{transition:none}
.brand:hover .brand-tree .lf,
.brand:focus-visible .brand-tree .lf,
.brand.bloom .brand-tree .lf{
  animation:leafBloom 1.15s cubic-bezier(.28,1.02,.36,1) both;
  animation-delay:calc((11 - var(--i)) * .055s);
}
/* Touch has no hover, so a tap is the equivalent gesture: js/click-leaves.js
   adds .bloom and removes it when the animation ends, so it re-triggers on
   every subsequent tap. Nothing fires unprompted. */
@media (hover:none){
  .brand:hover .brand-tree .lf{animation:none}
  .brand.bloom .brand-tree .lf{
    animation:leafBloom 1.15s cubic-bezier(.28,1.02,.36,1) both;
    animation-delay:calc((11 - var(--i)) * .055s);
  }
}
/* The original bounce, restored — I had flattened it to a monotonic ease-out,
   which removed the one thing that gave the mark its character. The overshoot
   is back, along with the slight fade in, but slower and softer than it was:
   1.15s instead of 0.95s, the peak eased down from 1.05 to 1.035, and the
   rotation kick reduced. It reads as a leaf unfurling and settling rather
   than a leaf popping. */
@keyframes leafBloom{
  0%{transform:scale(.74) rotate(-4.5deg);opacity:.7}
  50%{opacity:1}
  68%{transform:scale(1.035) rotate(1deg)}
  100%{transform:scale(1) rotate(0);opacity:1}
}
@media (prefers-reduced-motion:reduce){
  .brand:hover .brand-tree .lf,
  .brand:focus-visible .brand-tree .lf,
  .brand.bloom .brand-tree .lf{animation:none}
}

.nav-menu{display:flex;align-items:center;gap:2px;margin-left:auto;position:relative}
.nav-item{position:relative}
/* ── THE MENU TYPE ─ rebuilt from scratch ───────────────────────
   Poppins Light, uppercase, widely tracked. This face is used HERE AND
   NOWHERE ELSE on the site — `--menu` exists so the menu can be set
   independently of the body face without either one dragging the other
   around. Body and UI stay Inter; headings stay Cormorant.

   WHY THIS FACE. Two earlier attempts failed for opposite reasons. The LFFO
   Wordmark's roman cut is derived from TeX Gyre Termes, a Times clone, and
   at menu size read as exactly that — a generic serif. Inter is a fine UI
   face but it is a WORKHORSE: drawn for density and legibility in interface
   text, with the slightly condensed, tightly-fitted forms that job needs.
   Neither is slim, and neither is a display face. Poppins is geometric —
   its O is a true circle, its stems are even-width monolines, and at 300 it
   is genuinely thin rather than a regular weight lightened. Geometric sans
   against an elegant serif is the standard luxury pairing, and it is what
   makes this row read as premium rather than as an app toolbar.

   WHY UPPERCASE. Caps have no descenders and a single shared cap-height, so
   the row resolves into one even architectural band instead of a ragged mix
   of x-heights and ascenders. In a geometric face that band is the point:
   every letter is built from the same circle and the same stem, so tracked
   out at .19em the row reads as a measured sequence of marks.

   THE TRACKING IS THE DETAIL, AND IT HAS A COST. letter-spacing is inserted
   after the LAST glyph as well as between glyphs. Uncorrected, that trailing
   space sits inside the link's box and pushes the visible ink off-centre by
   half of it — at .19em that is a visible 2.5px lean, and it is exactly the
   misalignment wide tracking is blamed for. It is cancelled in both places
   it can appear: the link's right padding is short by precisely the tracking,
   and on the items that carry a chevron the label span takes a negative
   right margin of the same value so its own trailing space does not widen
   the .35em gap to the chevron. Every step-down below restates its own
   band's value, because a .19em correction under .12em of tracking would
   over-correct and lean the label the other way. */
.nav-link{
  display:flex;align-items:center;gap:.35em;
  padding:.72em calc(.86em - .19em) .72em .86em;
  border-radius:0;
  color:rgba(242,247,253,.95);
  font-family:var(--menu);font-weight:300;
  font-size:.78rem;letter-spacing:.19em;text-transform:uppercase;
  font-feature-settings:"kern" 1;
  white-space:nowrap;
  transition:color .22s var(--ease),padding .38s var(--ease-lux);
}
.site-header.condensed .nav-link{padding:.5em calc(.78em - .19em) .5em .78em}
/* History-aware: the current page reads in gold on the desktop bar too (quiet,
   no marker) — set by js/nav-history.js. */
.nav-menu .nav-link.is-current{color:var(--gold-bright)}

/* Seven tracked uppercase items is a wide row. It steps down through four
   bands rather than being sized for the narrowest case and left small
   everywhere — the size and the tracking come down together, since tracking
   is what costs the most width at this letter count. */
@media (max-width:1500px){
  .nav-link{font-size:.75rem;letter-spacing:.17em;
            padding:.72em calc(.72em - .17em) .72em .72em}
  .site-header.condensed .nav-link{padding:.5em calc(.64em - .17em) .5em .64em}
  .nav-link > span[data-i18n]{margin-right:-.17em}
}
@media (max-width:1400px){
  .nav-link{font-size:.73rem;letter-spacing:.15em;
            padding:.72em calc(.56em - .15em) .72em .56em}
  .site-header.condensed .nav-link{padding:.5em calc(.5em - .15em) .5em .5em}
  .nav-link > span[data-i18n]{margin-right:-.15em}
}
@media (max-width:1240px){
  .nav-link{font-size:.7rem;letter-spacing:.12em;
            padding:.72em calc(.4em - .12em) .72em .4em}
  .site-header.condensed .nav-link{padding:.5em calc(.36em - .12em) .5em .36em}
  .nav-link > span[data-i18n]{margin-right:-.12em}
  /* the plate and the language switch give up a little of their own air at
     this width too, so the step-down doesn't fall entirely on the type */
  .nav-right{gap:14px;margin-left:10px}
}
/* The last 40px before the bar collapses to the hamburger at 1080. Nothing
   is left to give here but the inter-item gap, so it goes. */
@media (max-width:1120px){
  .nav-menu{gap:0}
  .nav-link{font-size:.68rem;letter-spacing:.1em;
            padding:.72em calc(.3em - .1em) .72em .3em}
  .site-header.condensed .nav-link{padding:.5em calc(.28em - .1em) .5em .28em}
  .nav-link > span[data-i18n]{margin-right:-.1em}
}
.nav-link > span[data-i18n]{white-space:nowrap;margin-right:-.19em}
.nav-link:hover,.nav-item.open .nav-link{color:var(--gold-bright)}
/* Sliding gold underline — one indicator tracks the hovered item, injected and
   positioned by js/main.js. Smooth, single-hand motion; hidden at rest. */
.nav-underline{
  position:absolute;left:0;bottom:5px;height:2px;width:0;
  background:linear-gradient(90deg,var(--gold),var(--gold-bright));border-radius:2px;
  opacity:0;transform:translateX(0);pointer-events:none;z-index:1;
  transition:transform .4s var(--ease-lux),width .4s var(--ease-lux),opacity .25s var(--ease);
}
.nav-underline.show{opacity:1}
@media (prefers-reduced-motion:reduce){.nav-underline{transition:opacity .2s var(--ease)}}
.nav-link .chev{font-size:1.15em;transition:transform .25s var(--ease)}
.nav-item.open .nav-link .chev{transform:rotate(180deg)}

/* mega dropdown */
/* ── Why the frosted dropdown could never have worked ────────────────────
   It was translucent with a backdrop-filter, and it hangs off a header that
   had one too. An element with a backdrop-filter becomes a "backdrop root"
   for its subtree: everything inside it samples that element's
   already-composited output instead of the page behind. So the dropdown was
   never blurring the section beneath it — it was blurring the header's own
   filtered result, a nearly uniform slab. The panel came out flat, washed and
   grey, and no amount of tuning the alpha or the blur radius could have
   changed that; the geometry of the effect forbids it.

   It is also the wrong idea on its own terms. A menu is not something you
   look through. It is a surface you read, and a reading surface should be
   opaque, because every point of contrast it gives up is contrast the words
   lose. (The header itself is solid now, for a related reason — see the note
   on .site-header above.)

   So the panel is solid. Warm white, a hairline of the same colour family as
   the site's other rules rather than a grey border, a gold cap along the top
   edge tying it to the bar it hangs from, and the top step of the shadow
   scale so it reads as genuinely floating above the page. */
.dropdown{
  position:absolute;top:calc(100% + 10px);left:50%;transform:translateX(-50%) translateY(10px) scale(.985);
  min-width:288px;
  background:var(--surface-raised);
  border:1px solid var(--line);
  border-top:3px solid var(--gold);
  border-radius:var(--radius-lg);
  box-shadow:var(--edge-light),var(--shadow-xl);padding:10px;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .24s var(--ease-lux),transform .34s var(--ease-lux),visibility .24s;
}
/* invisible bridge over the gap so the cursor never leaves on the way down */
.dropdown::after{
  content:"";position:absolute;top:-16px;left:0;right:0;height:16px;
}
.nav-item.open .dropdown{opacity:1;visibility:visible;pointer-events:auto;transform:translateX(-50%) translateY(0) scale(1)}
/* Each row settles a beat after the panel, in reading order. It costs four
   declarations and it is the difference between a menu appearing and a menu
   arriving. */
.dropdown a{opacity:0;transform:translateY(5px);transition:background .18s var(--ease),opacity .3s var(--ease-lux),transform .3s var(--ease-lux),box-shadow .18s var(--ease)}
.nav-item.open .dropdown a{opacity:1;transform:none}
.nav-item.open .dropdown a:nth-child(1){transition-delay:.05s}
.nav-item.open .dropdown a:nth-child(2){transition-delay:.09s}
.nav-item.open .dropdown a:nth-child(3){transition-delay:.13s}
.nav-item.open .dropdown a:nth-child(4){transition-delay:.17s}
.nav-item.open .dropdown a:nth-child(5){transition-delay:.21s}
@media (prefers-reduced-motion:reduce){
  .dropdown,.dropdown a{transition:none}
  .dropdown a{opacity:1;transform:none}
}
/* The pointer reads as an extension of the gold cap, not as a separate shape
   floating above it: it is drawn 1px into the panel so the two share an edge. */
.dropdown::before{
  content:"";position:absolute;top:-9px;left:50%;transform:translateX(-50%);
  border:9px solid transparent;border-bottom-color:var(--gold);border-top:0;
  filter:drop-shadow(0 -1px 1px rgba(10,23,40,.10));
}
.dropdown a{
  display:flex;flex-direction:column;gap:2px;
  padding:.7em .85em;border-radius:var(--radius);
  transition:background .18s var(--ease);
}
/* A row answers with a warm ground, a gold rule that grows down its leading
   edge, and a small shift toward the reader — three cheap signals that
   together make it unmistakable which item is under the cursor. */
.dropdown a{position:relative}
.dropdown a::before{
  content:"";position:absolute;left:0;top:8px;bottom:8px;width:2px;
  background:var(--gold);border-radius:2px;
  transform:scaleY(0);transform-origin:center;
  transition:transform .3s var(--ease-lux);
}
.dropdown a:hover,.dropdown a:focus-visible{background:var(--cream);outline:none;transform:translateX(3px)}
.dropdown a:hover::before,.dropdown a:focus-visible::before{transform:scaleY(1)}
.dropdown a:focus-visible{box-shadow:0 0 0 2px var(--gold-bright)}
.dropdown a .d-title{font-weight:600;color:var(--navy);font-size:.94rem}
.dropdown a .d-sub{font-size:.78rem;color:var(--ink-soft)}
.dropdown a:hover .d-title{color:var(--brown)}

/* The language switch and the login plate are two separate controls and have
   to read as two. At 14px, with the plate carrying a 1px keyline and the
   switch ending in a bare "ES", they sat close enough to look like one
   component with a divider in it. */
.nav-right{display:flex;align-items:center;gap:24px;margin-left:18px}
.lang-switch{display:flex;align-items:center;gap:2px}
/* The menu's face, but REGULAR — not the menu's Light. These are two-letter
   codes, the shortest strings in the bar: at 300 there is not enough ink in
   an E or an S for the eye to settle on, and they read as faint marks rather
   than as a control. 400 is the plain weight of the same face, so the row
   stays one typographic system while the codes become legible. Never bold —
   they are a secondary control and outweighing the menu is what the previous
   600 got wrong.

   Tracking comes down with the weight going up. Wide tracking is what makes
   a Light all-caps row look considered; at Regular the same tracking just
   looks loose, and on a two-letter word it pushes the pair apart into two
   separate marks. .08em holds EN together as one word. */
.lang-btn{
  padding:.3em .52em;
  font-family:var(--menu);font-size:.76rem;font-weight:400;letter-spacing:.08em;
  color:rgba(255,255,255,.7);border-radius:3px;
  transition:color .22s var(--ease),text-shadow .28s var(--ease);
}
/* A soft gold glow lifts the code on hover — feedback is light, nothing moves. */
.lang-btn:hover,.lang-btn:focus-visible{color:var(--gold-bright);text-shadow:0 0 9px rgba(220,183,99,.75)}
/* Colour alone marks the selection — no weight change. Swapping weight as
   well moves the letters, which nudges every code after it along the row. */
.lang-btn.active{color:var(--gold)}
/* Translations are fetched the first time a language is chosen, so on a slow
   connection there is a real, if brief, wait between the click and the text
   changing. The button state has already answered; this just stops the pointer
   from implying nothing happened. */
.lang-loading .lang-btn{cursor:progress}
.lang-sep{color:rgba(255,255,255,.22);font-size:.72rem;font-weight:300}
/* The current language is removed from the switcher, not just de-emphasised;
   only the languages you can switch to remain. Two-class specificity so it wins
   over .lang-btn's own display without !important. */
.lang-btn.lang-hide,.lang-sep.lang-hide{display:none}
/* Compact language cycler — desktop uses the full EN/FR/DE/ES row above; the
   phone gets this single chip beside the menu button that shows the current
   language and rolls to the next on tap. Hidden on desktop. */
.lang-quick{display:none}
.lang-quick .lq-code{display:inline-block;line-height:1}
.lang-quick.lq-roll .lq-code{animation:lqRoll .3s var(--ease-lux)}
@keyframes lqRoll{
  0%{transform:translateY(0);opacity:1}
  45%{transform:translateY(-95%);opacity:0}
  55%{transform:translateY(95%);opacity:0}
  100%{transform:translateY(0);opacity:1}
}
@media (prefers-reduced-motion:reduce){.lang-quick.lq-roll .lq-code{animation:none}}
.nav-cta{padding:.55em 1.15em;font-size:.84rem;border-radius:0}
/* ── Member Login — THE KEY PLATE ────────────────────────────────────────────
   Rebuilt. What was here before was a translucent white pill-less slab with
   Signet registration brackets clamped to its corners — mark 06, which is not
   in the approved set, and which on a 28px-tall element rendered as four
   stray gold ticks that read as rendering artefacts rather than as a mark.
   The surface was a milky white wash that fought the navy bar instead of
   sitting in it, and the whole thing looked like a button that had lost its
   fill rather than a deliberate access control.

   The replacement is a PLATE, not a button: an engraved compartment set into
   the navy, divided by a hairline rule into a key chamber and a label. It
   carries two approved marks and nothing else —

     03 Ember Border — on approach the edge itself ignites: the hairline goes
        to full gold and a tight 6px ember is held right along it, no bloom
        escaping outward, nothing diffuse.
     05 Corner Spark — two 2px points, one at each end of the diagonal, lift
        from a quiet 30% to full and take a small halo. They never move.

   The key turns a few degrees in its chamber — a decorative element moving,
   which the mark language allows; the plate itself is rigid. Nothing about
   this element resizes, lifts or translates, on hover or on press. */
.nav-login{
  position:relative;display:inline-flex;align-items:stretch;gap:0;
  padding:0;line-height:1;
  background:linear-gradient(180deg,rgba(255,255,255,.055),rgba(255,255,255,.018));
  border:var(--hair) solid rgba(201,163,78,.34);
  color:rgba(255,255,255,.88);text-decoration:none;cursor:pointer;
  /* the plate is part of the menu row, so it takes the menu's face. Weight
     400 rather than the menu's 300: this one is a bordered control and
     needs a shade more body than a bare link to hold its own inside the
     frame, but it must not out-weigh the row it sits in — 600 did. */
  font-family:var(--menu);font-size:.7rem;font-weight:400;letter-spacing:.16em;text-transform:uppercase;
  white-space:nowrap;
  transition:background .34s var(--ease-lux),border-color .3s var(--ease-lux),
             color .3s var(--ease-lux),box-shadow .3s var(--ease-lux);
}
/* The key chamber — its own compartment, ruled off from the label. */
.nav-login .nl-ico{
  display:inline-grid;place-items:center;width:auto;height:auto;border:0;background:none;border-radius:0;
  padding:.92em .72em .92em .82em;
  color:var(--gold-bright);font-size:.96rem;
  transition:color .3s var(--ease-lux),transform .44s var(--ease-lux);
}
.nav-login .nl-ico i{font-size:1em;display:block}
.nav-login .nl-rule{
  width:var(--hair);align-self:stretch;flex:0 0 auto;
  background:linear-gradient(180deg,rgba(201,163,78,0),rgba(201,163,78,.42),rgba(201,163,78,0));
  transition:background .34s var(--ease-lux);
}
/* The label sat in .62em of vertical padding at .68rem — a 24px-tall plate
   with 11px type in it, which is what "squeezed" was: the caps were pressed
   against both hairlines with nothing to breathe into, and the trailing
   letter-space of the tracking pushed the last letter toward the right edge
   while the first letter still sat hard against the rule. The plate is now
   ~31px tall, and the label's right padding carries an extra .15em to
   absorb the trailing letter-space that uppercase tracking always adds
   after the final character. */
.nav-login .nl-text{display:inline-flex;align-items:center;white-space:nowrap;padding:.92em 1.05em .92em .9em}
/* 05 Corner Spark */
.nav-login::before,.nav-login::after{
  content:"";position:absolute;width:2px;height:2px;border-radius:50%;pointer-events:none;
  background:var(--gold-bright);opacity:.3;
  transition:opacity .32s var(--ease-lux),box-shadow .32s var(--ease-lux);
}
.nav-login::before{top:3px;left:3px}
.nav-login::after{bottom:3px;right:3px}
/* 03 Ember Border */
.nav-login:hover,.nav-login:focus-visible{
  outline:none;color:#fff;
  background:linear-gradient(180deg,rgba(201,163,78,.10),rgba(201,163,78,.03));
  border-color:var(--gold);
  box-shadow:0 0 0 var(--hair) var(--gold),0 0 6px rgba(201,163,78,.34);
}
.nav-login:hover::before,.nav-login:focus-visible::before,
.nav-login:hover::after,.nav-login:focus-visible::after{opacity:1;box-shadow:0 0 5px var(--gold-bright)}
.nav-login:hover .nl-rule,.nav-login:focus-visible .nl-rule{
  background:linear-gradient(180deg,rgba(201,163,78,0),rgba(220,183,99,.85),rgba(201,163,78,0))}
/* The key turns in the lock. */
.nav-login:hover .nl-ico,.nav-login:focus-visible .nl-ico{color:#fff;transform:rotate(-14deg)}
.nav-login:active{
  transition-duration:.09s;
  background:linear-gradient(180deg,rgba(201,163,78,.16),rgba(201,163,78,.06));
  box-shadow:0 0 0 var(--hair) var(--gold),0 0 3px rgba(201,163,78,.55),inset 0 1px 2px rgba(0,0,0,.22);
}
@media (prefers-reduced-motion:reduce){
  .nav-login,.nav-login .nl-ico,.nav-login .nl-rule,
  .nav-login::before,.nav-login::after{transition:none}
  .nav-login:hover .nl-ico,.nav-login:focus-visible .nl-ico{transform:none}
}

/* Creative morph: the icon takes a springy half-turn as the bars collapse into
   an X — the middle bar shrinks to a point rather than just fading — and settles
   on gold. One spring easing drives the whole gesture so it reads as a single
   turning motion, not three bars animating separately. Hover feedback is colour
   only (no motion), per the interaction rules. */
.nav-toggle{
  display:none;flex-direction:column;align-items:center;justify-content:center;
  gap:6px;width:44px;height:44px;padding:0;background:none;border:none;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:transform .52s cubic-bezier(.68,-.55,.27,1.55);
}
.nav-toggle span{
  display:block;width:24px;height:2px;background:var(--surface);border-radius:2px;transform-origin:center;
  transition:transform .46s cubic-bezier(.68,-.55,.27,1.55),opacity .26s var(--ease),background-color .3s var(--ease);
}
.nav-toggle:hover span,.nav-toggle:focus-visible span{background:var(--gold-bright)}
.nav-toggle.active{transform:rotate(180deg)}
.nav-toggle.active span{background:var(--gold-bright)}
.nav-toggle.active span:nth-child(1){transform:translateY(8px) rotate(45deg)}
.nav-toggle.active span:nth-child(2){transform:scaleX(0);opacity:0}
.nav-toggle.active span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}
@media (prefers-reduced-motion:reduce){
  .nav-toggle,.nav-toggle span{transition:none}
  .nav-toggle.active{transform:none}
}

/* =========================================================
   FOOTER
   ========================================================= */
.site-footer{background:#112a4c;color:rgba(255,255,255,.72);padding-top:clamp(48px,7vw,76px)}
.footer-top{
  display:grid;grid-template-columns:1.6fr 1fr 1fr 1.1fr;gap:36px;
  padding-bottom:40px;border-bottom:1px solid var(--line-navy);
}
/* Contact line under the social row — styled here rather than inline so the
   footer carries no ad-hoc styling that can drift. */
.foot-contact{margin-top:20px}
.foot-contact a{display:inline-flex;align-items:center;gap:6px}
.foot-contact i{font-size:.9em}
.footer-brand img{height:56px;width:auto;margin-bottom:18px}
.footer-brand p{font-size:.9rem;line-height:1.7;max-width:300px;color:rgba(255,255,255,.6)}

/* Footer inline logo — recreated italic-serif wordmark + colourful tree */
/* Sized by WIDTH, not height. At a fixed 58px height the mark rendered 527px
   wide inside a footer brand column of roughly 317px, so it ran under the next
   column: that was the misalignment, not the baseline. Constraining the width
   keeps it inside its column and flush-left with the tagline beneath it. */
.foot-logo{width:min(100%,320px);height:auto;display:block;margin-bottom:18px;overflow:visible;cursor:pointer}
/* The lockup measures 541 x 67 units, so at 320px wide it stands 40px tall.
   Below 720px the cap drops to 300px, which keeps it inside a phone's content
   column with the tagline still flush to the same left edge. */
@media (max-width:720px){
  .foot-logo{width:min(100%,300px)}
}
/* ── LFFO Wordmark Italic ────────────────────────────────────────────────
   The wordmark is outline paths generated from the face, so it never depends
   on a font resolving at run time. */
.fl-g{fill:#fff}

/* ── Written with a quill ────────────────────────────────────────────────
   Not a reveal. Each glyph is masked by its own pen centrelines, extracted as
   the medial axis of the letterform, and those centrelines are stroked open
   with dashoffset. Ink therefore appears along the path the nib travels, in
   stroke order, exactly as writing does: the stem of a 'b' before its bowl,
   the dot of an 'i' last.

   Every stroke's duration is proportional to its own length, so the nib holds
   ONE CONSTANT SPEED across the whole word. That is the detail that separates
   writing from animation: a wide 'm' genuinely takes longer to lay down than
   an 'i'. A 22ms lift sits between strokes, as when a nib leaves the paper. */
.fl-s{
  fill:none;stroke:#fff;stroke-linecap:round;stroke-linejoin:round;
  /* pathLength="100" on every stroke expresses the dash in percent of the REAL
     rendered curve length rather than an estimate of it. The estimate ran short
     on curved strokes, so the dash pattern repeated and leaked fragments of
     later letters into view ahead of the nib. */
  /* Explicit gap (100 200), not a bare 100: a single value repeats as dash-then-
     equal-gap, so any offset wraps part of the dash back into view. With a gap
     wider than the path nothing can wrap. opacity gates it as well, because a
     zero-length dash still paints a round linecap. */
  stroke-dasharray:100 200;stroke-dashoffset:100;opacity:0;
}
.foot-logo.written .fl-s{
  animation:flInk var(--t) linear var(--d) forwards;
}
@keyframes flInk{
  from{stroke-dashoffset:100;opacity:1}
  to{stroke-dashoffset:0;opacity:1}
}

/* The nib is the same path carrying a single short dash, so it is physically
   incapable of drifting out of sync with the ink it lays. */
.fl-nib{
  fill:none;stroke:var(--gold-bright);stroke-width:2.6;stroke-linecap:round;
  stroke-dasharray:0.7 200;stroke-dashoffset:0;opacity:0;
}
/* The glow is attached only while the word is being written. There are 91 nib
   paths in the mark; carrying a drop-shadow on all of them from first paint
   made the footer the most filtered element on the page for the sake of a
   two-and-a-half second effect. */
.foot-logo.written .fl-nib{filter:drop-shadow(0 0 3.5px rgba(220,183,99,.95))}
/* Once the writing has finished the nibs have nothing left to do, so they stop
   being painted at all. */
.foot-logo.write-done .fl-nibs{display:none}
.foot-logo.written .fl-nib{
  animation:flNib var(--t) linear var(--d) forwards;
}
@keyframes flNib{
  0%{stroke-dashoffset:0;opacity:1}
  97%{stroke-dashoffset:-100;opacity:1}
  100%{stroke-dashoffset:-100;opacity:0}
}

@media (prefers-reduced-motion:reduce){
  .fl-s{stroke-dashoffset:0;opacity:1}
  .foot-logo.written .fl-s,.foot-logo.written .fl-nib{animation:none}
  .fl-nib{display:none}
}
/* The footer group labels are h2, not h4. As h4 they skipped two ranks below
   the page h1 on every single page of the site — the one heading-order fault
   the audit found site-wide. Rank is semantics; the look is set here. */
.footer-col h2{color:var(--white);font-family:var(--sans);font-size:.8rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;margin-bottom:18px}
.footer-col ul li{margin-bottom:10px}
.footer-col ul a{font-size:.9rem;color:rgba(255,255,255,.68);transition:color .2s var(--ease)}
.footer-col ul a:hover{color:var(--gold)}
/* Link animation — DESKTOP (hover-capable devices) ONLY: a gold underline
   sweeps in beneath the label on hover. Gated by hover:hover so a touch screen
   never fires it — mobile taps stay still. */
@media (hover:hover){
  .footer-col ul a{position:relative}
  .footer-col ul a::after{
    content:"";position:absolute;left:0;right:0;bottom:-2px;height:1.5px;
    background:linear-gradient(90deg,var(--gold),var(--gold-bright));
    transform:scaleX(0);transform-origin:left;transition:transform .38s cubic-bezier(.22,1,.36,1);
  }
  .footer-col ul a:hover::after{transform:scaleX(1)}
}
@media (hover:hover) and (prefers-reduced-motion:reduce){
  .footer-col ul a::after{transition:none}
}
.footer-social{display:flex;gap:12px;margin-top:6px}
.footer-social a{
  width:38px;height:38px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.06);color:rgba(255,255,255,.75);
  transition:all .22s var(--ease);
}
.footer-social a:hover{background:var(--gold);color:var(--navy)}
.footer-social i{font-size:1.15rem}
.footer-bottom{
  display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:14px;
  padding-block:22px;font-size:.82rem;color:rgba(255,255,255,.5);
}
.footer-bottom a{color:rgba(255,255,255,.6)}
.footer-bottom a:hover{color:var(--gold)}
.footer-legal{display:flex;gap:22px;flex-wrap:wrap}

/* ═══ Unified card OUTLINE ══════════════════════════════════════════════════
   Every content card keeps its OWN design; only the frame is the shared box
   outline — a gold hairline, 8px corners. This base holds on MOBILE unchanged.
   Tiers (.tier, .jt) are excluded. */
.kh-card,.lib-card,.country-card,.value-card,.board-member,
.mission,.event-card,.k-card,.summer-card{
  border:1px solid rgba(201,163,78,.34) !important;
  border-radius:8px !important;
}
/* DESKTOP ONLY (≥821px): crisper corners + a premium hover — a smooth elevate
   on a spring-eased curve, the frame igniting to gold, and a soft GOLD GLOW
   layered over a deep drop shadow. Mobile is left exactly as above. */
@media (min-width:821px){
  .kh-card,.lib-card,.country-card,.value-card,.board-member,
  .mission,.event-card,.k-card,.summer-card{
    border-radius:4px !important;
  }
  .kh-card,.country-card,.value-card,.board-member,
  .mission,.event-card,.k-card,.summer-card{
    transition:transform .46s cubic-bezier(.34,1.12,.38,1),
               box-shadow .46s cubic-bezier(.34,1.12,.38,1),
               border-color .3s var(--ease) !important;
  }
  .kh-card:hover,.lib-card:hover,.lib-card:focus-visible,.country-card:hover,
  .value-card:hover,.board-member:hover,.mission:hover,.event-card:hover,
  .k-card:hover,.summer-card:hover{
    transform:translateY(-6px) !important;
    border-color:var(--gold) !important;
    /* Cleaner, closer shadow — the reach is pulled in so it hugs the card
       instead of spilling far below it. A tight depth shadow + a faint gold
       halo, nothing diffuse. */
    box-shadow:0 12px 24px -14px rgba(6,14,26,.44),
               0 0 13px -5px rgba(201,163,78,.3),
               0 2px 6px -4px rgba(6,14,26,.12) !important;
  }
}
@media (min-width:821px) and (prefers-reduced-motion:reduce){
  .kh-card:hover,.lib-card:hover,.lib-card:focus-visible,.country-card:hover,
  .value-card:hover,.board-member:hover,.mission:hover,.event-card:hover,
  .k-card:hover,.summer-card:hover{transform:none !important}
}

/* =========================================================
   REUSABLE PIECES
   ========================================================= */
/* page hero (interior pages) */
.page-hero{
  background:var(--navy);color:var(--white);
  padding-block:clamp(60px,9vw,110px);position:relative;overflow:hidden;
}
/* The old single corner radial is gone: the shared lit-navy treatment in
   css/pages-fx.css now lights every dark section, and leaving this in place
   double-lit the top-right corner of all eight interior heroes. */
.page-hero .container{position:relative;z-index:1}
/* ── Interior page H1 — set in the association's own hand ────────────────────
   The eight interior headings are the one place on the site where LFFO
   Wordmark Italic is used as live type. It is used quietly: the face is a
   high-contrast italic and it does the work on its own, so the weight comes
   DOWN to 400 (600 clogged the hairlines), the negative tracking the sans
   headings carry is released to a fractionally positive figure, and the size
   is nudged down — an italic of this contrast reads larger than a roman at
   the same measure, and matching the old size made it shout.

   Nothing else on the site uses it. Below ~18px the hairlines break up, so it
   stays away from every button and control by design.

   padding-left with a matching negative margin: the italic's first glyph
   overhangs its own origin, and .page-hero h1 sits at the container edge with
   an animation on it. The pair gives the overhang room without moving the
   optical left edge by a pixel. */
.page-hero h1{
  color:var(--white);max-width:820px;
  font-family:"LFFO Wordmark",var(--serif);font-style:italic;font-weight:400;
  font-size:clamp(2.2rem,4.7vw,3.7rem);letter-spacing:.004em;line-height:1.1;
  padding-left:.06em;margin-left:-.06em;
}
.page-hero p{color:rgba(255,255,255,.75);font-size:1.12rem;max-width:620px;margin-top:18px}
.breadcrumb{display:flex;gap:.5em;align-items:center;font-size:.82rem;color:rgba(255,255,255,.55);margin-bottom:22px}
.breadcrumb a:hover{color:var(--gold)}
.breadcrumb i{font-size:1em;opacity:.6}

/* ═══════════════════════════════════════════════════════════════════════
   LIT NAVY — every dark section on the site, not just the home hero
   ═══════════════════════════════════════════════════════════════════════
   The home hero was given a proper lighting model: a vignette falling to
   near-black at the corners, a warm gold source high on one side, a cold blue
   ray raking across, and a pool of lifted blue where the copy sits. Every
   OTHER navy surface on the site — the eight interior page heroes, the
   seminars band, the best-practice band, the join and presence sections —
   was still a single flat fill. Side by side that reads as two different
   sites, and flat navy is the one background that always looks cheap,
   because nothing in the physical world is evenly lit.

   Applied here as one shared treatment, tuned down from the hero's: these
   are chapter headings, not the front door, so the range is narrower and the
   ray is fainter. Painted with pseudo-elements rather than by rewriting each
   section's background, so any existing background (the presence map's navy,
   a seasonal wash) survives underneath. */
.page-hero,
.lit-navy{
  position:relative;isolation:isolate;
  background-color:var(--navy-lit);
}
.page-hero::before,
.lit-navy::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  /* Soft lighting only — no edge vignette. The old vignette darkened each
     section toward its own corners, which turned every navy passage into a lit
     BOX; stacked, two boxes met in a dark band with a hard seam. These are two
     wide, gentle glows over the flat navy base, so adjacent navy sections read
     as one continuous field with no edge. */
  /* Fixed-PIXEL glow sizes, not percentages: a percentage-sized glow scales
     with the section, so a short section (the join band) gets over-filled and
     its glow reaches the top edge — which is exactly what re-created the seam
     against the taller presence band above it. At a fixed height the glow stays
     contained in every section's middle, so all navy edges are pure base and
     any two navy passages meet seamlessly. */
  background:
    radial-gradient(640px 220px at 78% 44%,rgba(216,176,88,.08),transparent 74%),
    radial-gradient(680px 220px at 22% 56%,rgba(38,76,128,.13),transparent 76%);
}
/* The blue ray, at half the hero's strength. Skewed and heavily blurred so it
   stays a shaft of light rather than a stripe. */
.page-hero::after,
.lit-navy::after{
  content:"";position:absolute;top:-40%;left:-8%;width:44%;height:180%;
  z-index:-1;pointer-events:none;
  background:linear-gradient(94deg,transparent,rgba(74,157,192,.09) 40%,rgba(120,190,225,.11) 52%,transparent 100%);
  transform:rotate(14deg);filter:blur(30px);
}
/* The original page-hero corner glow is superseded by the layers above; it was
   a single 340px radial pinned to the top right and it now double-lights that
   corner. */
.page-hero > .container{position:relative;z-index:1}

/* ── The interior heroes get their own pass, brighter than the shared one ──
   Sat next to the home hero, the shared lit-navy treatment above read as
   correct but thin: a chapter heading is allowed to be quieter than the
   front door, but "quieter" had drifted into "flatter," and a shorter
   section has less room for a faint glow to resolve in before the edge cuts
   it off. This does not touch .lit-navy itself — the seminars, best-practice,
   join and presence bands keep the original, subtler pass — it only lifts
   the two glows and the ray specifically where the hero is the first thing a
   reader sees on the page. */
.page-hero::before{
  background:
    radial-gradient(720px 260px at 78% 42%,rgba(222,186,104,.19),transparent 74%),
    radial-gradient(760px 260px at 21% 58%,rgba(58,108,172,.26),transparent 76%);
}
.page-hero::after{
  background:linear-gradient(94deg,transparent,rgba(90,175,210,.19) 40%,rgba(142,208,240,.22) 52%,transparent 100%);
}

/* No gold horizon line. It drew a hard 1px gold rule at the bottom of every
   navy band — a sharp edge, and doubly so where one navy section met another.
   Navy passages now end without a rule; the change of section does the work. */
.lit-navy{border-bottom:none}

@media (prefers-reduced-motion:reduce){
  .page-hero::after,.lit-navy::after{filter:blur(30px)}
}

/* leaf divider dots */
.leaf-dots{display:inline-flex;gap:6px;margin-bottom:10px}
.leaf-dots span{width:9px;height:9px;border-radius:50% 50% 50% 0;transform:rotate(45deg)}

/* Cards sat at zero elevation and only gained a shadow on hover, so a grid of
   them read as flat panes ruled onto the page. They now rest one step above
   the surface with a lit top edge, and hover is a genuine lift from one real
   elevation to a higher one — which is what makes the movement legible. */
.card{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);
  overflow:hidden;box-shadow:var(--edge-light),var(--shadow-sm);
  transition:transform .34s var(--ease-lux),box-shadow .34s var(--ease-lux),border-color .3s var(--ease);
}
.card:hover{transform:translateY(-5px);box-shadow:var(--edge-light),var(--shadow-lg);border-color:var(--gold-soft)}

/* ---------- Reveal animation ---------- */
.reveal{opacity:0;transform:translateY(24px);transition:opacity .7s var(--ease),transform .7s var(--ease)}
/* Snappier, shorter-travel reveals on mobile so stacked cards don't feel laggy */
@media (max-width:720px){
  .reveal{transform:translateY(14px);transition:opacity .45s var(--ease),transform .45s var(--ease)}
}
.reveal.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .reveal{opacity:1;transform:none;transition:none}
  html{scroll-behavior:auto}
}

/* =========================================================
   RESPONSIVE — NAV
   ========================================================= */
@media (max-width:1080px){
  .nav-menu,.nav-right .lang-switch,.nav-cta,.nav-right .nav-login{display:none}
  .nav-toggle{display:flex}
  /* The compact language chip appears beside the menu button on the phone. */
  .nav-right .lang-quick{
    display:inline-flex;align-items:center;justify-content:center;overflow:hidden;
    min-width:36px;height:34px;padding:0 9px;
    font-family:var(--menu);font-size:.72rem;font-weight:400;letter-spacing:.09em;
    color:var(--gold-bright);background:none;border:1px solid rgba(201,163,78,.42);border-radius:6px;
    cursor:pointer;-webkit-tap-highlight-color:transparent;
    transition:border-color .25s var(--ease),box-shadow .25s var(--ease),color .25s var(--ease);
  }
  .nav-right .lang-quick:hover,.nav-right .lang-quick:focus-visible{
    border-color:var(--gold);color:#fff;box-shadow:0 0 9px rgba(201,163,78,.45);outline:none;
  }
  .nav-right .lang-quick:active{box-shadow:0 0 12px rgba(220,183,99,.6)}
  .nav-right{margin-left:0}

  /* Same glass as the bar, one step more opaque because it carries the whole
     menu over live page content. The top edge tracks the bar's height so the
     sheet stays welded to it while the header condenses. */
  /* Solid, for the same reason as the bar above: it covers a white page, so a
     translucent navy would read grey rather than as glass. */
  .mobile-nav{
    position:fixed;top:74px;left:0;right:0;bottom:0;z-index:98;
    /* White, modern ground — the sheet reads as paper, not a dark panel; the
       navy stays on the header bar above it. Dark ink text, warm hairlines,
       gold accents carried over. */
    background:#fff;
    transform:translateX(100%);
    transition:transform .42s var(--ease-lux),top .42s var(--ease-lux);
    overflow-y:auto;-webkit-overflow-scrolling:touch;
    padding:14px var(--pad) 32px;
    display:flex;flex-direction:column;
  }
  .site-header.condensed ~ .mobile-nav{top:54px}
  /* Opening the menu returns the header to its FULL height even when scroll has
     condensed it — the sheet then reads from a full-size lockup — and it
     re-condenses on close. .menu-open beats .condensed by carrying one more class. */
  .site-header.condensed.menu-open .nav-bar{height:74px}
  .site-header.condensed.menu-open .brand-logo{transform:none}
  .site-header.condensed.menu-open ~ .mobile-nav{top:74px}
  .mobile-nav.open{transform:translateX(0)}
  /* Rows arrive in sequence once the sheet has landed, the same courtesy the
     desktop dropdown gets. */
  .mobile-nav .m-access,.mobile-nav .m-item,.mobile-nav .m-foot{
    opacity:0;transform:translateX(14px);
    transition:opacity .34s var(--ease-lux),transform .34s var(--ease-lux);
  }
  .mobile-nav.open .m-access,.mobile-nav.open .m-item,.mobile-nav.open .m-foot{opacity:1;transform:none}
  /* Access row is child 1, the seven items 2–8, the foot 9 — staggered by
     document order so the sheet fills top-to-bottom. */
  .mobile-nav.open > *:nth-child(1){transition-delay:.07s}
  .mobile-nav.open > *:nth-child(2){transition-delay:.11s}
  .mobile-nav.open > *:nth-child(3){transition-delay:.15s}
  .mobile-nav.open > *:nth-child(4){transition-delay:.19s}
  .mobile-nav.open > *:nth-child(5){transition-delay:.23s}
  .mobile-nav.open > *:nth-child(6){transition-delay:.27s}
  .mobile-nav.open > *:nth-child(7){transition-delay:.31s}
  .mobile-nav.open > *:nth-child(8){transition-delay:.35s}
  .mobile-nav.open > *:nth-child(9){transition-delay:.39s}
  @media (prefers-reduced-motion:reduce){
    .mobile-nav,.mobile-nav .m-access,.mobile-nav .m-item,.mobile-nav .m-foot{transition:none}
    .mobile-nav .m-access,.mobile-nav .m-item,.mobile-nav .m-foot{opacity:1;transform:none}
    .site-header.condensed ~ .mobile-nav{top:74px}
  }

  /* Evenly spaced rows, one hairline each; the LAST item drops its rule so the
     seam before the footer is a single line, not two (the item's own border
     plus the foot's used to stack). */
  .m-item{border-bottom:1px solid var(--line)}
  .m-item:nth-last-child(2){border-bottom:none}
  /* The seven items share the space between the login and the language row
     equally, so the list sits evenly through the middle of the sheet rather than
     bunched at the top with a gap beneath. Each item grows but never shrinks, so
     on a short phone (or with a sub-menu open) it simply scrolls instead. */
  .mobile-nav .m-item{flex:0 0 auto;display:flex;flex-direction:column;justify-content:center}
  .m-link-row{display:flex;align-items:center;justify-content:space-between;gap:12px}
  .m-link{
    display:block;
    padding:.8em 0;color:var(--navy);font-size:1.04rem;font-weight:500;
    text-align:left;flex:1;letter-spacing:.01em;
  }
  .m-link:active{color:var(--gold)}
  /* ── History-aware states (js/nav-history.js) ──────────────────────────────
     The current page carries a gold edge-bar flush to the sheet's left edge —
     "you are here" — and reads in gold; pages already visited this session
     carry a small gold dot after their label. */
  .mobile-nav .m-link{position:relative}
  .mobile-nav .m-link.is-current{color:var(--gold-deep);font-weight:600}
  .mobile-nav .m-link.is-current::before{
    content:"";position:absolute;left:calc(-1 * var(--pad));top:50%;transform:translateY(-50%);
    width:3px;height:1.25em;border-radius:0 2px 2px 0;
    background:linear-gradient(180deg,var(--gold-bright),var(--gold));
    box-shadow:0 0 9px rgba(201,163,78,.5);
  }
  .m-hist{
    display:inline-block;width:5px;height:5px;margin-left:9px;border-radius:50%;
    background:rgba(201,163,78,.6);vertical-align:middle;position:relative;top:-1px;
  }
  /* E3 — the expand control is an engraved plate that lights from within when
     its section opens (04 Inner Glow), and the section label lights a gold
     ledge-sweep beneath it at the same moment. Two coordinated marks; the row
     itself never moves. */
  .m-toggle{
    position:relative;overflow:hidden;
    display:flex;align-items:center;justify-content:center;
    width:42px;height:42px;padding:0;cursor:pointer;flex:0 0 auto;
    background:none;border:1px solid rgba(201,163,78,.4);border-radius:6px;color:var(--gold-bright);
    transition:border-color .3s var(--ease);
  }
  .m-toggle::before{
    content:"";position:absolute;inset:0;pointer-events:none;
    background:radial-gradient(ellipse at center,rgba(201,163,78,.32),transparent 70%);
    opacity:0;transition:opacity .38s var(--ease-lux,ease);
  }
  .m-item.open .m-toggle::before{opacity:1}
  .m-item.open .m-toggle{border-color:rgba(201,163,78,.6)}
  .m-toggle .chev{position:relative;z-index:2;transition:transform .35s cubic-bezier(.34,1.3,.5,1);color:var(--gold-deep);font-size:1.5rem;opacity:.95}
  .m-item.open .m-toggle .chev{transform:rotate(180deg)}
  /* the label's gold sweep — text-width, so it underlines "About", not the row */
  .m-item.has-sub .m-link{flex:0 1 auto;position:relative}
  .m-item.has-sub .m-link::after{
    content:"";position:absolute;left:0;right:0;bottom:calc(1em - 5px);height:1.6px;
    background:linear-gradient(90deg,var(--gold),var(--gold-bright),var(--gold));
    box-shadow:0 0 7px rgba(201,163,78,.5);
    transform:scaleX(0);transform-origin:left;transition:transform .42s cubic-bezier(.22,1,.36,1);
  }
  .m-item.has-sub.open .m-link::after{transform:scaleX(1)}
  .m-sub{position:relative;max-height:0;overflow:hidden;opacity:0;transition:max-height .42s cubic-bezier(.4,0,.2,1),opacity .3s var(--ease)}
  /* A gold vertical rule runs down the left of the sub-list, gathering the
     sub-links into their parent as one indented group. It is drawn on the sheet
     and grows with the panel (scaleY from the top) so it reads as the section
     opening, not a static bar. */
  .m-sub::before{
    content:"";position:absolute;left:3px;top:2px;bottom:6px;width:1.5px;border-radius:1px;
    background:linear-gradient(180deg,var(--gold-bright),var(--gold) 55%,rgba(201,163,78,.35));
    box-shadow:0 0 6px rgba(201,163,78,.4);
    transform:scaleY(0);transform-origin:top;transition:transform .42s cubic-bezier(.22,1,.36,1) .06s;
  }
  .m-item.open .m-sub::before{transform:scaleY(1)}
  .m-sub a{display:block;padding:.6em 0 .6em 20px;color:var(--ink-soft);font-size:.92rem;transform:translateX(-6px);transition:transform .3s var(--ease),color .2s var(--ease)}
  .m-sub a:active{color:var(--gold)}
  .m-item.open .m-sub{padding-bottom:6px;opacity:1}
  .m-item.open .m-sub a{transform:translateX(0)}
  @media (prefers-reduced-motion:reduce){
    .m-sub::before{transition:none;transform:scaleY(1)}
  }

  /* Footer: CTA + language, kept compact and always reachable */
  /* The login plate is not a .btn, so the .btn margin below never applied to
     it and the plate sat flush against the language row — the two touched.
     The foot owns the rhythm now rather than relying on a child's margin. */
  /* Login, item list and language settle as one compact stack from the top;
     the leftover room falls at the natural bottom edge of the sheet rather
     than as balloon padding through the rows or a void mid-sheet. On a short
     phone the list simply scrolls. */
  .mobile-nav .m-foot{
    margin-top:30px;padding-top:22px;border-top:1px solid var(--line);
    display:flex;flex-direction:column;gap:14px;
  }
  .m-foot-label{
    font-size:.64rem;letter-spacing:.24em;text-transform:uppercase;
    color:var(--gold-deep);font-weight:600;
  }
  .mobile-nav .btn{width:100%;justify-content:center;padding:.95em 1.6em;font-size:1rem}
  /* wraps rather than clips: four full language names is a wide row and the
     narrowest phones cannot hold it on one line at any size worth reading */
  .m-lang{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-start}
  /* The header switcher is four two-letter codes and is tracked to match the
     menu beside it. These are the same buttons carrying FULL language names,
     four across a phone — the menu's tracking is inherited here and pushes
     "Español" off the edge, so it is wound back. Tracking is for short
     all-caps marks, not for words. */
  .m-lang .lang-btn{
    color:var(--ink-soft);font-size:.88rem;font-weight:400;letter-spacing:.02em;
    padding:.5em .8em;border:1px solid var(--line);border-radius:6px;min-height:40px;
  }
  .m-lang .lang-btn:hover,.m-lang .lang-btn:focus-visible{color:var(--navy);border-color:var(--gold)}
  /* The gold fill already says which one is selected; bolding it as well was
     saying it twice, and it reflowed the pill's width on every switch. */
  .m-lang .lang-btn.active{color:var(--navy);background:var(--gold);border-color:var(--gold)}
}
@media (min-width:1081px){.mobile-nav{display:none}}
/* Very short screens: allow scroll but keep items tight */
@media (max-width:1080px) and (max-height:680px){
  .m-link{padding:.58em 0;font-size:.96rem}
  .m-sub a{padding:.5em 0 .5em 14px}
}

/* ── Mobile footer — refined ─────────────────────────────────────────────────
   The brand sits first. Below it the two link columns form ONE faint tinted
   panel capped by a single gold line — no rule between the columns, comfortable
   inner room. CONNECT closes the footer as a MATCHING tinted panel carrying its
   social marks and contact line, so the lower footer reads as one considered
   block gold-capped in two places. A gold seam caps the whole footer and the
   legal links are parted by gold dots. Link hover-animation is DESKTOP-ONLY (see
   the hover:hover rule in the base footer styles). Mobile only — the desktop
   footer layout is untouched. */
@media (max-width:820px){
  /* gold seam across the very top of the footer */
  .site-footer{position:relative;padding-top:clamp(34px,6vw,50px)}
  .site-footer::before{
    content:"";position:absolute;top:0;left:50%;transform:translateX(-50%);
    width:min(70%,320px);height:2px;border-radius:2px;
    background:linear-gradient(90deg,transparent,rgba(201,163,78,.6),transparent);
  }
  .footer-top{grid-template-columns:1fr 1fr;column-gap:0;row-gap:0;padding-bottom:0;border-bottom:0}

  /* 1 — brand: a composed lockup — a larger centred wordmark, a short gold rule,
     then the tagline set to a matching measure. The rule ties the mark to the
     line beneath it so the block reads as one considered unit, not a small logo
     floating over loose text. */
  .footer-brand{grid-column:1/-1;text-align:center;padding-bottom:28px}
  .footer-brand .foot-logo{width:min(78%,252px);margin:0 auto}
  .footer-brand p{
    position:relative;margin:17px auto 0;padding-top:17px;
    font-size:.84rem;line-height:1.62;max-width:286px;
  }
  .footer-brand p::before{
    content:"";position:absolute;top:0;left:50%;transform:translateX(-50%);
    width:46px;height:2px;border-radius:2px;
    background:linear-gradient(90deg,var(--gold),var(--gold-bright),var(--gold));
  }

  /* group labels → plain gold eyebrows, flush with the links beneath them */
  .footer-col h2{color:var(--gold-bright);font-size:.68rem;letter-spacing:.2em;margin-bottom:15px}
  .footer-col ul li{margin-bottom:9px}
  .footer-col ul a{font-size:.88rem}

  /* 2 — the two link columns as ONE tinted panel capped by a single gold line,
     with comfortable left/right room; no rule between the two columns. */
  .footer-brand + .footer-col,
  .footer-brand + .footer-col + .footer-col{
    background:rgba(255,255,255,.03);
    border-top:1px solid rgba(201,163,78,.5);
    padding:22px 16px 20px;
  }
  .footer-brand + .footer-col{padding-left:22px}
  .footer-brand + .footer-col + .footer-col{padding-left:24px;padding-right:22px}

  /* 3 — CONNECT last: a MATCHING tinted panel with its own gold cap, centred.
     The social marks are hairline gold rings that fill on interaction; the email
     is a small bordered contact chip rather than loose text, so the block reads
     as composed. */
  .footer-col:last-child{
    grid-column:1/-1;text-align:center;
    background:rgba(255,255,255,.03);
    border-top:1px solid rgba(201,163,78,.5);
    padding:24px 20px 24px;
  }
  .footer-col:last-child h2{text-align:center;margin-bottom:18px;letter-spacing:.24em}
  .footer-col:last-child .footer-social{justify-content:center;gap:13px;margin:0}
  .footer-social a{
    width:44px;height:44px;background:transparent;
    border:1px solid rgba(201,163,78,.34);color:rgba(255,255,255,.82);
    transition:background .22s var(--ease),border-color .22s var(--ease),color .22s var(--ease),box-shadow .22s var(--ease);
  }
  .footer-social a:hover,.footer-social a:active{
    background:var(--gold);border-color:var(--gold);color:var(--navy);
    box-shadow:0 0 14px rgba(201,163,78,.35);
  }
  .footer-col:last-child .foot-contact{margin-top:18px}
  .footer-col:last-child .foot-contact a{
    display:inline-flex;align-items:center;gap:7px;
    padding:.5em 1.05em;border:1px solid rgba(201,163,78,.3);border-radius:4px;
    color:rgba(255,255,255,.86);font-size:.86rem;
    transition:border-color .22s var(--ease),color .22s var(--ease),background .22s var(--ease);
  }
  .footer-col:last-child .foot-contact a:hover{border-color:var(--gold);color:#fff;background:rgba(201,163,78,.08)}

  /* bottom bar — centred, refined: legal links parted by gold dots and lighting
     gold on hover, copyright quietened. */
  .footer-bottom{flex-direction:column;align-items:center;text-align:center;gap:12px;padding-block:18px 20px}
  .footer-bottom > span{font-size:.78rem;color:rgba(255,255,255,.45);line-height:1.55;max-width:320px}
  .footer-legal{justify-content:center;gap:0;flex-wrap:wrap}
  .footer-legal a{padding:0 15px;position:relative;transition:color .2s var(--ease)}
  .footer-legal a:hover{color:var(--gold-bright)}
  .footer-legal a + a::before{
    content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
    width:3px;height:3px;border-radius:50%;background:rgba(201,163,78,.5);
  }
}
@media (max-width:520px){
  .footer-brand + .footer-col,
  .footer-brand + .footer-col + .footer-col{text-align:left}
  .footer-brand + .footer-col ul,
  .footer-brand + .footer-col + .footer-col ul{display:block;text-align:left}
  .footer-social{justify-content:center}
  .footer-legal a{padding:0 12px}
}

/* ── "Not sure which applies to you?" ────────────────────────────────────────
   Slimmer. It was a 760px card with 22/30 padding, a shadow and a 1.25rem
   heading — a box the size of a content section asking a one-line question,
   which made a small aside look like a major step in the page. It is now a
   narrower, lower band on a hairline with no shadow: the question reads as an
   aside, which is what it is.

   The buttons follow the approved lab set instead of inventing their own
   behaviour. At rest they are an engraved hairline and a label; on approach
   they take 03 Ember Border (the edge itself ignites, tight, nothing diffuse)
   and 01 Ledge Glow settles a hairline underneath. Selected state is the one
   filled moment. Nothing lifts, scales or translates — same rule as every
   other control on the site. */
.tier-guide{
  max-width:640px;margin:0 auto 22px;padding:15px 24px 17px;text-align:center;
  background:var(--surface);border:var(--hair) solid var(--line);border-radius:0;
}
.tier-guide h3{font-size:1.06rem;margin-bottom:3px}
.tier-guide p{font-size:.86rem;margin-bottom:13px;color:var(--ink-soft)}
.tier-guide-btns{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
.tg-btn{
  position:relative;overflow:hidden;
  padding:.62em 1.15em;border-radius:0;
  border:var(--hair) solid rgba(15,32,56,.36);
  background:transparent;color:var(--ink);
  font-family:var(--sans);font-weight:600;font-size:.84rem;letter-spacing:.03em;
  cursor:pointer;
  transition:color .3s var(--ease-lux),background-color .3s var(--ease-lux),
             border-color .3s var(--ease-lux),box-shadow .34s var(--ease-lux);
}
/* 05 Corner Spark — two quiet points, brightness only, nothing moves. */
.tg-btn::before,.tg-btn::after{
  content:"";position:absolute;width:2px;height:2px;border-radius:50%;
  background:var(--gold-deep);opacity:.26;pointer-events:none;
  transition:opacity .3s var(--ease-lux),box-shadow .3s var(--ease-lux);
}
.tg-btn::before{top:5px;left:5px}
.tg-btn::after{bottom:5px;right:5px}
/* 03 Ember Border + 01 Ledge Glow */
.tg-btn:hover,.tg-btn:focus-visible{
  outline:none;color:var(--navy);border-color:var(--gold);
  box-shadow:0 0 0 var(--hair) var(--gold),0 0 6px rgba(201,163,78,.34),
             0 var(--hair) 0 var(--gold);
}
.tg-btn:hover::before,.tg-btn:hover::after,
.tg-btn:focus-visible::before,.tg-btn:focus-visible::after{opacity:1;box-shadow:0 0 5px var(--gold-deep)}
.tg-btn:active{transition-duration:.09s;box-shadow:inset 0 1px 2px rgba(10,23,40,.14)}
.tg-btn.active{background:var(--gold);border-color:var(--gold-deep);color:#241a09}
.tg-btn.active::before,.tg-btn.active::after{background:#241a09;opacity:.4;box-shadow:none}
/* Tertiary — a text action, not a button (08 Underline Sweep). */
/* It carries .btn-sweep, so the hover mark is mark 08 out of the lab and not a
   second underline invented here — the rule that fills in left to right is the
   one every other tertiary action on the site uses.

   What is added on top is a RESTING hairline at 30%, on the span's ::before.
   Without it the control was bare text: it appears only after a filter has been
   applied, so a reader meets it with no affordance at all and nothing to say it
   can be pressed. With it there is a quiet rule under the words at rest, and
   the lab's sweep runs over that rule at full strength on approach. Two layers,
   one line: the mark is unchanged, it now has something to sweep across. */
.tg-reset{
  position:relative;font-family:var(--sans);font-size:.8rem;font-weight:600;
  letter-spacing:.02em;
  color:var(--ink-soft);background:none;border:none;cursor:pointer;
  margin-top:11px;padding:.2em 0;text-decoration:none;
  transition:color .24s var(--ease);
}
.tg-reset > span{position:relative;display:inline-block}
.tg-reset > span::before{
  content:"";position:absolute;left:0;right:0;bottom:-5px;height:1px;
  background:currentColor;opacity:.3;transition:opacity .24s var(--ease);
}
.tg-reset:hover,.tg-reset:focus-visible{color:var(--gold-deep);outline:none}
.tg-reset:hover > span::before,.tg-reset:focus-visible > span::before{opacity:0}
@media (prefers-reduced-motion:reduce){
  .tg-btn,.tg-btn::before,.tg-btn::after,.tg-reset,.tg-reset > span::before{transition:none}
}

@media (max-width:640px){
  .tier-guide{
    max-width:none;margin:0 0 18px;padding:16px 16px 18px;
    text-align:left;border-radius:0;
  }
  .tier-guide h3{font-size:1.06rem;line-height:1.28;margin-bottom:5px}
  .tier-guide p{font-size:.88rem;margin-bottom:13px}
  .tier-guide-btns{flex-direction:column;gap:10px;flex-wrap:nowrap}
  .tg-btn{
    position:relative;display:flex;align-items:center;
    width:100%;min-height:52px;padding:.85em 1.1em .85em 1.35em;
    border-radius:var(--radius-lg);text-align:left;font-size:.98rem;
    line-height:1.3;
  }
  .tg-btn::before{
    content:"";position:absolute;left:0;top:10px;bottom:10px;width:3px;
    border-radius:0 3px 3px 0;background:var(--gold);
    transform:scaleY(0);transform-origin:center;
    transition:transform .28s var(--ease);
  }
  .tg-btn.active::before{transform:scaleY(1)}
  .tg-btn.active{padding-left:1.45em}
  .tg-reset{margin-top:16px;min-height:44px;display:inline-flex;align-items:center}
}

/* =========================================================
   SECTION DIVIDER — v2 (logo-tree palette + damped swing)
   ---------------------------------------------------------
   Built to the v2 rebuild spec, which supersedes everything that was here
   before. The geometry is authored, not derived; the colour is sampled from
   the leaves of the tree in the logo; the motion is a damped pendulum.

   WHERE THESE GO — the placement system, unchanged.

   A divider marks a change of MOVEMENT: the page has finished saying one
   thing and is about to start saying another. Ten exist on the whole site.

   1. LIGHT GROUND ONLY. The spec ships .to-dark and .on-dark variants for
      navy boundaries; the placements here still avoid them, so variants 11
      and 12 (red drop, ice pebble) are held in reserve rather than used.
   2. NEVER FIRST, NEVER LAST — not between the hero and the first section,
      not directly above the footer.
   3. NEVER TWICE IN A ROW — at least one full section between any two.
   4. THREE PER PAGE, MAXIMUM.
   5. NOT ON WORKING SURFACES — library.html is a filter tool; contact.html
      and consultation.html are single-task pages with no second movement.

   Which gives: about 3 · index 2 · knowledge 2 · events 1 · membership 1 ·
   partners 1 · library, contact, consultation none. The variant sequence
   runs green → sky → khaki → apricot → terracotta in document order across
   the site, so a reader walks from spring toward autumn as they go.
   ========================================================= */
:root{
  /* leaf palette — the median pixel of each leaf blob in the logo artwork,
     trunk excluded. These are measured values, not approximations of the
     older --leaf-* tokens, which stay where they are used elsewhere. */
  --tree-green:      #80ad51;
  --tree-sky:        #52b1d8;
  --tree-khaki:      #c4a173;
  --tree-apricot:    #e6994e;
  --tree-terracotta: #d85c3e;
  --tree-red:        #c43034;
  --tree-ice:        #c5e0e3;
  /* The navy the lit sections actually paint. The divider bands bridge INTO
     those sections, so they have to use this exact value and not --navy: the
     v2 spec's #0f2038 is four steps darker than #14325c, which rendered every
     bridge as a visibly darker strip laid across the seam it was supposed to
     hide. One token, so the two can never drift apart again. */
  --navy-lit:        #14325c;
  --ease-out-soft: cubic-bezier(.22,.61,.36,1);   /* line growth */
  --ease-swing:    cubic-bezier(.45,0,.55,1);     /* sinusoidal half-swing */
}

.section-divider{
  display:flex;align-items:center;justify-content:center;
  height:56px;position:relative;overflow:visible;
  pointer-events:none;
  background:transparent;
}
.section-divider.on-dark{background:var(--navy-lit)}
/* The upper half is TRANSPARENT, not cream. It was painting var(--cream)
   unconditionally, but the section it bridges FROM is not always cream — the
   Knowledge Hub above it is white — so the bridge laid a cream strip across a
   white section and the seam it was meant to hide became two seams. Letting
   the top half show through means it is always exactly the colour of whatever
   sits above it, on every page, without knowing which section that is. */
.section-divider.to-dark{
  background:linear-gradient(180deg,
    transparent 0%,transparent 50%,var(--navy-lit) 50%,var(--navy-lit) 100%);
}
/* A bridge is half cream and half navy, so a single line colour cannot read on
   both halves. Each half takes the ground it sits on: warm line into the cream,
   gold out over the navy — and the leaf lands exactly on the seam between them. */
.section-divider.to-dark .divider-line.left{
  background:linear-gradient(270deg,
    color-mix(in srgb,var(--lc,var(--gold)) 55%,var(--line)),var(--line) 60%,transparent)}
.section-divider.to-dark .divider-line.right{
  background:linear-gradient(90deg,var(--gold),rgba(255,255,255,.16) 62%,transparent)}
.section-divider.on-dark .divider-line{
  background:linear-gradient(270deg,var(--gold),rgba(255,255,255,.12) 60%,transparent)!important;
}
.section-divider.on-dark .divider-line.right{
  background:linear-gradient(90deg,var(--gold),rgba(255,255,255,.12) 60%,transparent)!important;
}

/* ---------- the leaf ---------- */
.divider-leaf{
  position:relative;z-index:2;
  width:var(--leaf-size,12px);height:var(--leaf-size,12px);
  background:var(--lc,var(--gold));
  border-radius:var(--leaf-shape,50% 0 50% 50%);
  transform:translate3d(0,0,0) rotate(var(--leaf-rot,45deg));
  opacity:0;
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.12));
  will-change:transform,opacity;
  backface-visibility:hidden;
}
.section-divider.landed .divider-leaf{
  animation:leaf-drift var(--leaf-fall,1.9s) linear forwards;
}
/* Damped pendulum. The overall track is linear; each keyframe carries its own
   sinusoidal ease, so every half-swing accelerates out of one extreme and
   decelerates into the next. That per-keyframe easing is the load-bearing
   detail — a single easing across the whole track flattens the swings.

   Amplitude decays ~35% per swing and the sign alternates; horizontal throw
   and tilt decay together. The vertical fall NEVER reverses — only x and
   rotation oscillate, because a leaf that bobs upward reads as a balloon.
   scaleX dips to .88 at the fastest part of the swing and returns to 1 at
   rest: the leaf turning edge-on into the airflow.

   The transform function list is identical in every keyframe
   (translate3d rotate scaleX). Mismatched lists force matrix interpolation
   and the rotation goes wrong. */
@keyframes leaf-drift{
  0%{
    transform:translate3d(calc(var(--leaf-sway,14px) * -1),-38px,0)
              rotate(calc(var(--leaf-rot,45deg) - 26deg)) scaleX(.94);
    opacity:0;
    animation-timing-function:cubic-bezier(.45,0,.55,1);
  }
  15%{
    transform:translate3d(calc(var(--leaf-sway,14px) * -.30),-30.5px,0)
              rotate(calc(var(--leaf-rot,45deg) - 13deg)) scaleX(.97);
    opacity:.9;
    animation-timing-function:cubic-bezier(.45,0,.55,1);
  }
  30%{
    transform:translate3d(calc(var(--leaf-sway,14px) * .64),-24px,0)
              rotate(calc(var(--leaf-rot,45deg) + 14deg)) scaleX(.88);
    opacity:.9;
    animation-timing-function:cubic-bezier(.45,0,.55,1);
  }
  55%{
    transform:translate3d(calc(var(--leaf-sway,14px) * -.43),-12px,0)
              rotate(calc(var(--leaf-rot,45deg) - 8deg)) scaleX(.94);
    opacity:.88;
    animation-timing-function:cubic-bezier(.45,0,.55,1);
  }
  78%{
    transform:translate3d(calc(var(--leaf-sway,14px) * .21),-4px,0)
              rotate(calc(var(--leaf-rot,45deg) + 4deg)) scaleX(.98);
    opacity:.86;
    animation-timing-function:cubic-bezier(.45,0,.55,1);
  }
  92%{
    transform:translate3d(calc(var(--leaf-sway,14px) * -.07),-1px,0)
              rotate(calc(var(--leaf-rot,45deg) - 1.5deg)) scaleX(1);
    opacity:.85;
    animation-timing-function:cubic-bezier(.45,0,.55,1);
  }
  100%{
    transform:translate3d(0,0,0) rotate(var(--leaf-rot,45deg)) scaleX(1);
    opacity:.85;
  }
}

/* ---------- the two hairline halves ----------
   Laid out at their final 40% and revealed with scaleX. Animating width put a
   layout pass on every frame of every divider on the page; transform runs on
   the compositor, and the gradient sweeps out with the line instead of being
   re-cut each frame. */
/* Longer than the spec's 40%: at 40% the two halves read as a short dash
   floating mid-page rather than a rule crossing it. 46% each side carries the
   line most of the way out before the gradient releases it. */
.divider-line{
  position:absolute;top:50%;height:1px;width:46%;
  transform:scaleX(0);
  will-change:transform;
  background:linear-gradient(90deg,
    color-mix(in srgb,var(--lc,var(--gold)) 55%,var(--line)),
    var(--line) 60%,
    transparent);
  transition:transform 1s var(--ease-out-soft) .95s;
}
.divider-line.left{
  right:50%;transform-origin:100% 50%;
  background:linear-gradient(270deg,
    color-mix(in srgb,var(--lc,var(--gold)) 55%,var(--line)),
    var(--line) 60%,transparent);
}
.divider-line.right{left:50%;transform-origin:0 50%}
.section-divider.landed .divider-line{transform:scaleX(1)}

/* ---------- colour bloom at the landing point ---------- */
.divider-bloom{
  position:absolute;top:50%;left:50%;
  width:6px;height:6px;border-radius:50%;
  transform:translate(-50%,-50%) scale(0);
  background:radial-gradient(circle,
    color-mix(in srgb,var(--lc,var(--gold)) 40%,transparent),transparent 70%);
  transition:transform 1.3s var(--ease-out-soft) .85s,
             opacity 1.5s ease .85s;
  opacity:0;
  will-change:transform,opacity;
}
.section-divider.landed .divider-bloom{
  transform:translate(-50%,-50%) scale(9);
  opacity:.5;
}

@media (max-width:720px){
  /* Shorter throw on narrow screens so the leaf never drifts near the edge —
     but a LONGER rule proportionally, because on a 390px viewport a 46% half
     is only ~180px and the divider stops reading as a full-width gesture. */
  .section-divider{margin-block:0;--leaf-sway:9px}
  .divider-line{width:49%}
}

/* Reduced motion: appear, don't move. */
@media (prefers-reduced-motion:reduce){
  .section-divider.landed .divider-leaf{
    animation:none;opacity:.85;
    transform:translate3d(0,0,0) rotate(var(--leaf-rot,45deg)) scaleX(1);
  }
  .divider-line,.divider-bloom{transition:none}
}

/* =========================================================
   MEMBER LOGIN POPUP + member-access state
   ---------------------------------------------------------
   Two things were wrong here and both are fixed at the root rather than
   patched at the surface.

   1. THE FIELDS DID NOT LINE UP. The popup's inputs were styled by the
      generic `.field` rules — which live in css/pages.css. The homepage does
      not load css/pages.css. So on index.html the labels lost display:block
      and the inputs lost width:100%, EMAIL rendered as a bare input while
      PASSWORD rendered inside a flex wrapper, and the two fields sat at
      different widths and different left edges. Every rule the dialog needs
      now lives HERE, in the one stylesheet every page loads, under its own
      .login-* names, and both fields are built from one identical structure:
      label / .login-control / error slot. There is nothing left for them to
      disagree about.

   2. THE HEAD WAS A CUBE. A 52px navy square holding a lock icon, dropped
      onto a cream card — an object sitting ON the popup rather than part of
      it. It is replaced by the CANOPY below.
   ========================================================= */
.login-modal{position:fixed;inset:0;z-index:300;display:flex;align-items:center;justify-content:center;padding:20px}
.login-modal[hidden]{display:none}
/* Light frosted veil over the LIVE page — a gentle blur and a faint navy wash,
   so the site stays legible behind the popup. Fades out as well as in. */
.login-backdrop{position:absolute;inset:0;background:rgba(16,33,58,.24);
  -webkit-backdrop-filter:blur(7px) saturate(1.03);backdrop-filter:blur(7px) saturate(1.03);
  animation:lgFade .34s var(--ease-lux) both}
/* Soft-surface card: near-white with a faint translucency, a hairline edge and
   layered depth beneath — a calm pane resting above the page, never a slab.
   overflow:hidden so the canopy can bleed to all three of its top edges. */
.login-card{
  position:relative;z-index:1;width:min(438px,100%);overflow:hidden;
  background:linear-gradient(180deg,rgba(255,255,255,.98),rgba(252,250,245,.98));
  border:var(--hair) solid rgba(231,223,205,.9);border-radius:0;
  box-shadow:0 2px 6px rgba(8,17,33,.08),
             0 18px 40px -12px rgba(8,17,33,.28),
             0 40px 90px -20px rgba(8,17,33,.30);
  padding:0 clamp(30px,4.4vw,44px) clamp(30px,4.4vw,44px);
  transform-origin:center;
  animation:lgUp .46s var(--ease-lux) both;
}
/* Exit: JS adds .closing for the duration of the reverse animation. */
.login-modal.closing .login-backdrop{animation:lgFadeOut .28s var(--ease) both}
.login-modal.closing .login-card{animation:lgDown .28s var(--ease) both}
@keyframes lgFade{from{opacity:0}to{opacity:1}}
@keyframes lgFadeOut{from{opacity:1}to{opacity:0}}
@keyframes lgUp{from{opacity:0;transform:scale(.96) translateY(6px)}to{opacity:1;transform:scale(1) translateY(0)}}
@keyframes lgDown{from{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.975) translateY(4px)}}

/* ── THE CANOPY ──────────────────────────────────────────────────────────────
   What replaces the navy cube. Not a badge and not a banner: a navy field
   that runs edge to edge across the top of the card, holding four layers of
   the site's own visual language and then dissolving into the card's surface
   colour so there is no seam where it ends.

     · the tree's concentric GROWTH RINGS, struck from a centre below the
       card's lower edge so only their upper arcs cross the field — the same
       geometry as mark 09, at architectural scale
     · a warm BLOOM off-centre, the light the rings are catching
     · LEAVES in seven of the twelve colours taken from the logo artwork
       itself, drifting on long, unequal cycles so the field never visibly
       repeats
     · the KEY, drawn as engraved gold line-work — hairline strokes, no fill,
       no box — which inscribes itself once as the dialog opens

   The head type sits ON this field in cream, which is what makes it read as
   somewhere you have arrived rather than as decoration above a form. */
.login-canopy{
  position:relative;z-index:0;
  position:absolute;top:0;left:0;right:0;z-index:0;
  height:226px;overflow:hidden;
  background:
    radial-gradient(120% 130% at 50% 122%, rgba(28,52,84,.95) 0%, rgba(15,32,56,0) 62%),
    linear-gradient(165deg, var(--navy-deep) 0%, var(--navy) 58%, #0d1c31 100%);
}
.lc-rings{position:absolute;left:50%;bottom:-2px;width:132%;height:auto;transform:translateX(-50%);opacity:.85}
.lc-bloom{
  position:absolute;left:50%;bottom:-46%;width:74%;height:150%;transform:translateX(-50%);
  background:radial-gradient(ellipse at 50% 100%,rgba(201,163,78,.22) 0%,rgba(201,163,78,.07) 38%,rgba(201,163,78,0) 68%);
  pointer-events:none;
}
.lc-leaves{position:absolute;inset:0;pointer-events:none}
.lc-leaves i{
  position:absolute;left:var(--x);top:var(--y);
  width:var(--s);height:var(--s);background:var(--c);
  border-radius:58% 0 58% 58%;
  transform:rotate(var(--r));transform-origin:60% 60%;
  opacity:.3;filter:saturate(.82);
  animation:lcDrift 17s var(--ease-lux) var(--d) infinite;
}
/* A long, gentle drift with an odd period, so no two leaves ever line up and
   the field never reads as a loop. Nothing here glows or pulses. */
@keyframes lcDrift{
  0%,100%{transform:rotate(var(--r)) translate(0,0);opacity:.26}
  38%    {transform:rotate(calc(var(--r) + 9deg)) translate(3px,-5px);opacity:.44}
  71%    {transform:rotate(calc(var(--r) - 6deg)) translate(-3px,3px);opacity:.32}
}
.lc-key{
  position:absolute;left:50%;top:30%;transform:translate(-50%,-50%);
  width:44px;height:44px;color:var(--gold-bright);
  filter:drop-shadow(0 0 9px rgba(201,163,78,.34));
}
.lc-key svg{width:100%;height:100%;display:block}
/* The key inscribes itself once, on open. It does not repeat. */
.lc-key .lk-draw{stroke-dasharray:72;stroke-dashoffset:72;animation:lkDraw .95s var(--ease-lux) .16s forwards}
@keyframes lkDraw{to{stroke-dashoffset:0}}
/* The dissolve. The canopy does not stop at a line — it becomes the card.
   Held to the bottom quarter and to a soft ramp: a taller, heavier fade
   washed a milky band up through the middle of the navy and the title sat in
   fog rather than on a field. */
.lc-fade{
  position:absolute;left:0;right:0;bottom:0;height:20%;pointer-events:none;
  background:linear-gradient(180deg,rgba(252,250,245,0) 0%,rgba(252,250,245,.08) 42%,rgba(252,250,245,.46) 74%,rgba(252,250,245,.97) 100%);
}
/* Head type, set INTO the canopy — cream on navy, which is what makes the
   dialog read as somewhere you have arrived rather than as a form with a
   picture above it.

   The canopy is taken OUT of flow and the head reserves its height instead.
   Pulling the head up over an in-flow canopy with a negative margin shortened
   the flow by that much and dragged the form up with it, so the EMAIL label
   ended up printed in ink-soft grey on top of the navy field, invisible. The
   head now owns the canopy's full height as its own minimum, which means the
   form can only ever begin below it, at any type size and in any language. */
.login-head{
  position:relative;z-index:2;text-align:center;
  min-height:226px;padding:106px 0 0;margin:0 0 28px;
}
.login-head h2{
  font-family:var(--serif);font-size:1.78rem;font-weight:600;color:#f6f2e9;
  margin:0 0 7px;letter-spacing:.012em;
  text-shadow:0 1px 14px rgba(8,17,33,.5);
}
.login-head p{
  font-size:.87rem;color:rgba(240,236,226,.76);letter-spacing:.015em;line-height:1.5;
  max-width:31ch;margin:0 auto;
  text-shadow:0 1px 10px rgba(8,17,33,.5);
}

.login-x{
  position:absolute;top:12px;right:12px;z-index:4;width:34px;height:34px;
  display:grid;place-items:center;
  background:transparent;border:var(--hair) solid rgba(255,255,255,.16);
  color:rgba(255,255,255,.72);cursor:pointer;font-size:1rem;
  transition:color .24s var(--ease),border-color .24s var(--ease),background .24s var(--ease);
}
.login-x:hover,.login-x:focus-visible{
  outline:none;color:#fff;border-color:var(--gold);background:rgba(201,163,78,.14);
}

/* ── FIELDS — self-contained, and identical to one another ───────────────────
   Both fields are label / .login-control / error. The control is the box: it
   owns the border, the well and the focus ring, and the input inside it is a
   transparent, borderless, full-width text surface. That is what makes EMAIL
   and PASSWORD align — the eye toggle sits INSIDE the same box rather than
   changing its shape, so a field with a button in it and a field without one
   are the same object at the same width with the same left edge. */
.login-form .login-field{margin-bottom:18px}
.login-form label{
  display:block;
  font-family:var(--sans);font-size:.68rem;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);
  margin:0 0 8px;transition:color .25s var(--ease);
}
.login-control{
  display:flex;align-items:stretch;width:100%;
  background:var(--surface-2);
  border:var(--hair) solid var(--line);border-radius:0;
  box-shadow:var(--inset-well);
  transition:border-color .25s var(--ease),box-shadow .3s var(--ease-lux),background .25s var(--ease);
}
.login-control input{
  flex:1 1 auto;min-width:0;width:100%;
  padding:.86em 1em;margin:0;
  background:transparent;border:0;border-radius:0;outline:none;box-shadow:none;
  font-family:inherit;font-size:.95rem;color:var(--ink);
}
.login-control input::placeholder{color:#9aa4b1}
.login-control:hover{border-color:var(--brown-soft)}
/* Elegant focus: the well lifts to lit-white, a soft gold ring appears and the
   label warms to gold. The ring is on the CONTROL, so both fields light
   identically — the password field's button is inside the lit box, not
   beside it. */
.login-field:focus-within .login-control{
  background:#fff;border-color:var(--gold);
  box-shadow:0 0 0 3px rgba(201,163,78,.15),0 1px 2px rgba(10,23,40,.05);
}
.login-field:focus-within label{color:var(--gold-deep)}
.login-eye{
  flex:0 0 auto;width:42px;display:grid;place-items:center;
  background:transparent;border:0;border-left:var(--hair) solid transparent;
  color:var(--ink-soft);cursor:pointer;font-size:1rem;
  transition:color .22s var(--ease),border-color .22s var(--ease);
}
.login-eye:hover,.login-eye:focus-visible{outline:none;color:var(--gold-deep);border-left-color:var(--line)}
.login-eye.is-on{color:var(--gold-deep)}
.login-err{display:block;min-height:1em;margin-top:6px;font-size:.78rem;color:#c0432f}
.login-field .login-control:has(input.is-invalid),
.login-control input.is-invalid{border-color:#c0432f}
.login-field:focus-within .login-control:has(input.is-invalid){
  box-shadow:0 0 0 3px rgba(192,67,47,.14)}
.login-formerr{background:rgba(192,67,47,.08);border:var(--hair) solid rgba(192,67,47,.32);color:#a5361f;
  font-size:.85rem;padding:.6em .8em;margin:0 0 14px;text-align:center}
.login-submit{width:100%;justify-content:center;margin-top:4px}
.login-submit.is-busy{opacity:.7;pointer-events:none}
.login-alt{text-align:center;font-size:.85rem;color:var(--ink-soft);margin:16px 0 0}
.login-alt a{color:var(--gold-deep);font-weight:600}
body.login-open{overflow:hidden}

@media (prefers-reduced-motion:reduce){
  .lc-leaves i{animation:none}
  .lc-key .lk-draw{animation:none;stroke-dashoffset:0}
}

/* Authenticated header state — the plate is signed in: the chamber holds a
   lit key, the sparks are already up, the edge carries a permanent warm
   hairline. Same geometry, so nothing shifts when the state changes. */
.nav-login.is-authed{
  color:#fff;border-color:rgba(220,183,99,.62);
  background:linear-gradient(180deg,rgba(201,163,78,.14),rgba(201,163,78,.05));
}
.nav-login.is-authed::before,.nav-login.is-authed::after{opacity:.85}
.nav-login.is-authed .nl-rule{
  background:linear-gradient(180deg,rgba(201,163,78,0),rgba(220,183,99,.7),rgba(201,163,78,0))}
/* Mobile member-login, lifted to the TOP of the sheet and given real presence:
   an engraved gold-hairline plate carrying the key mark, a thin vertical gold
   rule, and the label — a proper members' entrance rather than loose text.
   Feedback is 04 Inner Glow: a gold radial swells from the plate centre on
   press / focus. Nothing lifts, scales or translates. */
/* The plate sits on the LEFT, sharing the exact left edge of the nav items
   below it so the whole sheet reads off one clean vertical line. */
.m-access{display:flex;justify-content:flex-start;margin:20px 0 24px}
.nav-login-m{
  width:auto;justify-content:center;align-items:center;gap:0;
  position:relative;overflow:hidden;
  background:linear-gradient(180deg,rgba(201,163,78,.07),rgba(201,163,78,.02));
  border:1px solid rgba(201,163,78,.42);border-radius:8px;
  padding:.66em 1.15em .66em 1em;
  /* deep gold reads on the white sheet where gold-bright would wash out */
  font-size:.82rem;letter-spacing:.2em;color:var(--gold-deep);
  transition:border-color .3s var(--ease,ease),color .3s var(--ease,ease);
}
.nav-login-m .nl-ico{padding:0;margin-right:.66em;color:var(--gold-deep);font-size:1.02rem;display:flex;align-items:center;position:relative;z-index:2}
.nav-login-m .nl-rule{
  display:block;width:1px;align-self:stretch;margin-right:.66em;position:relative;z-index:2;
  background:linear-gradient(180deg,rgba(201,163,78,0),rgba(220,183,99,.75),rgba(201,163,78,0));
}
.nav-login-m .nl-text{padding:0;position:relative;z-index:2}
/* 04 Inner Glow — a gold radial that swells from the plate centre */
.nav-login-m::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:radial-gradient(ellipse at center,rgba(201,163,78,.30),transparent 70%);
  opacity:0;transition:opacity .34s var(--ease-lux,ease);
}
.nav-login-m::after{display:none}
.nav-login-m:hover,.nav-login-m:focus-visible{background:linear-gradient(180deg,rgba(201,163,78,.07),rgba(201,163,78,.02));border-color:rgba(201,163,78,.72);color:var(--gold-deep);box-shadow:none}
.nav-login-m:hover::before,.nav-login-m:focus-visible::before{opacity:1}
.nav-login-m:active::before{opacity:1}
.nav-login-m:active{border-color:rgba(220,183,99,.85)}

/* Once a member is signed in, the membership controls read as unlocked. */
body.lffo-member .khf-members .khf-lock,
body.lffo-member .lib-chip-mem i,
body.lffo-member .kh-foot .kh-meta i{color:var(--leaf-green)}

/* Unlock confirmation toast */
.lffo-toast{position:fixed;left:50%;bottom:26px;transform:translate(-50%,20px);z-index:320;
  display:flex;align-items:center;gap:.5em;background:var(--navy);color:#fff;
  padding:.8em 1.3em;font-size:.9rem;font-weight:600;box-shadow:0 12px 30px rgba(8,17,33,.4);
  opacity:0;transition:opacity .35s var(--ease),transform .35s var(--ease-lux);pointer-events:none}
.lffo-toast i{color:var(--gold-bright);font-size:1.15em}
.lffo-toast.in{opacity:1;transform:translate(-50%,0)}

/* Phone: the card takes the full width it is given, and the canopy's negative
   margin has to track the card's horizontal padding exactly or the navy field
   stops short of the edges and the bleed breaks. Both are set here together. */
@media (max-width:480px){
  .login-card{width:100%;padding:0 20px 26px}
  .login-canopy{height:206px}
  .login-head{min-height:206px;padding-top:96px;margin-bottom:24px}
  .login-head h2{font-size:1.54rem}
}
@media (prefers-reduced-motion:reduce){
  .login-backdrop,.login-card{animation:none}
  .lffo-toast{transition:none}
}

/* =========================================================
   CTA BAND — the bough
   ---------------------------------------------------------
   The first attempt framed the box with two gold rules interrupted at every
   corner and dropped a leaf into each gap. Interrupting all four corners on
   both rules meant eight cuts in a frame that is only there to feel solid, and
   the leaves — being static ornaments — had nothing to do with the leaf
   language the rest of the site speaks.

   This is a BOUGH instead. One idea, three parts:

   · The frame is CONTINUOUS. A single hairline, unbroken, all the way round,
     with a second fainter rule inset from it. Nothing is cut, which was the
     complaint and was also the right complaint: a plate reads as engraved
     because its edge does not stop.

   · Along the top edge runs a heavier gold line — the bough — drawn out from
     the CENTRE to both ends exactly as a section divider draws, on the same
     curve and the same duration. It is the same gesture the reader has already
     seen five times on the way down the page.

   · Three leaves FALL ONTO IT. Not placed: they use the divider's own leaf —
     the same seasonal tree palette, the same border-radius silhouettes, the
     same damped-pendulum keyframes out of leaf-drift — so a leaf landing on a
     CTA and a leaf landing on a divider are the same object doing the same
     thing. js/cta-leaves.js builds them; the variant table is the divider's.

   The result carries the identity without spending it, and every line in it is
   whole.
   ========================================================= */
.cta-band{
  position:relative;border-radius:0;
  padding:clamp(48px,5.6vw,72px) clamp(28px,5vw,60px) clamp(40px,5vw,60px);
  text-align:center;isolation:isolate;
}
/* The two continuous rules. */
.cta-band::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  border:1px solid rgba(201,163,78,.5);
}
.cta-band::after{
  content:"";position:absolute;inset:9px;pointer-events:none;z-index:1;
  border:1px solid rgba(201,163,78,.24);
  transition:border-color .45s var(--ease-lux);
}
.cta-band:hover::after,.cta-band:focus-within::after{border-color:rgba(220,183,99,.4)}

/* ── The bough ────────────────────────────────────────────────────────────
   Two halves growing out from the centre, so the line arrives the way a
   divider's does. .grown is added by js/cta-leaves.js when the band is in
   view — never on load, so the reader sees it happen. */
.cta-bough{position:absolute;left:0;right:0;top:-1px;height:2px;z-index:2;pointer-events:none}
.cta-bough i{
  position:absolute;top:0;height:2px;width:50%;display:block;
  background:linear-gradient(90deg,transparent,var(--gold) 42%,var(--gold-bright));
  transform:scaleX(0);
  transition:transform 1.05s var(--ease-lux) .1s;
}
.cta-bough i:first-child{left:0;transform-origin:100% 50%}
.cta-bough i:last-child{left:50%;transform-origin:0 50%;
  background:linear-gradient(270deg,transparent,var(--gold) 42%,var(--gold-bright))}
.cta-band.grown .cta-bough i{transform:scaleX(1)}

/* ── The leaves, straight out of the divider ──────────────────────────────
   Same custom properties the divider's leaf uses (--leaf-size, --leaf-shape,
   --leaf-rot, --leaf-sway, --lc) and the same leaf-drift keyframes, so there is
   exactly one falling-leaf-lands-on-a-line animation on this site and the CTA
   is a second user of it rather than a lookalike. */
.cta-band .cl{
  position:absolute;top:-1px;z-index:3;pointer-events:none;
  width:var(--leaf-size,13px);height:var(--leaf-size,13px);
  margin-top:calc(var(--leaf-size,13px) / -2 + 1px);
  margin-left:calc(var(--leaf-size,13px) / -2);
  background:var(--lc,var(--gold));
  border-radius:var(--leaf-shape,50% 0 50% 50%);
  transform:translate3d(0,0,0) rotate(var(--leaf-rot,45deg));
  opacity:0;
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.16));
  backface-visibility:hidden;
}
.cta-band.grown .cl{animation:leaf-drift var(--leaf-fall,1.9s) linear var(--d,0s) forwards}

@media (max-width:720px){
  .cta-band{padding:38px 22px 32px}
  .cta-band::after{inset:7px}
}
@media (prefers-reduced-motion:reduce){
  .cta-bough i{transform:scaleX(1);transition:none}
  .cta-band .cl{opacity:1;animation:none}
}

/* =========================================================
   MEMBERS-ONLY MARK  ·  the golden spark
   ---------------------------------------------------------
   A control that filters to member-only material should say so before it is
   pressed, and say it in the identity's own terms rather than with a padlock
   glyph doing all the work. Every members-only filter carries a single gold
   point at its top-right corner that breathes — one spark, 4.5 seconds, never
   moving, only brightening. It is the Corner Spark mark (05) reduced to one
   corner and given a slow pulse, so it reads as "this is lit for members"
   without becoming a second animation competing with the page.
   ========================================================= */
.mem-spark{position:relative}
.mem-spark::after{
  content:"";position:absolute;top:5px;right:6px;width:3px;height:3px;border-radius:50%;
  background:var(--gold);pointer-events:none;z-index:3;
  animation:memSpark 4.5s ease-in-out infinite;
}
@keyframes memSpark{
  0%,100%{opacity:.34;box-shadow:0 0 0 rgba(201,163,78,0)}
  50%    {opacity:1;  box-shadow:0 0 5px rgba(220,183,99,.85)}
}

/* =========================================================
   TRAVELLING SPARK  ·  a point of light running the border
   ---------------------------------------------------------
   For the two gated categories — Guidance and Training — a single spark runs
   the whole perimeter and comes back to where it started, once every seven
   seconds. It is drawn as a conic gradient masked to a one-pixel ring, so it
   follows the border exactly: at the corners it turns, it never cuts across
   the box, and because the angle is a registered @property it interpolates as
   an angle rather than being re-parsed as a string, which is what makes the
   loop seamless rather than jumping at 360°.

   The ring is masked, not drawn, so the button's own border, radius and fill
   are untouched and the effect costs one composited pseudo-element.
   ========================================================= */
.spark-run{position:relative;isolation:isolate}
.spark-run::before{
  content:"";position:absolute;inset:-1px;border-radius:inherit;pointer-events:none;z-index:2;
  padding:1px;
  background:conic-gradient(from var(--lffo-glow),
    transparent 0deg,transparent 300deg,
    rgba(201,163,78,.30) 330deg,var(--gold-bright) 352deg,
    rgba(201,163,78,.30) 358deg,transparent 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  animation:lffoTravel 7s linear infinite;
  opacity:.9;
}
.spark-run:hover::before{opacity:1;animation-duration:3.6s}
@media (prefers-reduced-motion:reduce){
  .mem-spark::after{animation:none;opacity:.7}
  .spark-run::before{animation:none;opacity:.35}
}

/* Lock badge is hidden by default (mobile is untouched); it only appears in the
   desktop block below. */
.kh-lock-badge{display:none}

/* ═══ DESKTOP-ONLY card & filter refinements ═══════════════════════════════
   Corners are locked at 4px (in the card-outline block above). Here: the
   category top-bar is blended into the plate, members-only cards are locked
   with a breathing gold badge, and every filter button carries the travelling
   gold perimeter shine. All of this is ≥821px only — mobile stays as shipped. */
@media (min-width:821px){

  /* — the category top-bar blends in: a soft side-fade + slight transparency so
       it settles under the gold outline rather than capping it hard. */
  .kh-card .kh-top{
    height:3px;opacity:.9;
    background:linear-gradient(90deg,transparent,var(--c,var(--gold-bright)) 15%,var(--c,var(--gold-bright)) 85%,transparent);
  }

  /* — members-only cards: a gold lock badge, top-right, breathing softly and
       filling gold on hover. Signed-in members see it resolve to green. */
  .kh-card[data-members="true"]{position:relative}
  .kh-lock-badge{
    display:flex;align-items:center;justify-content:center;
    position:absolute;top:11px;right:11px;z-index:5;
    width:30px;height:30px;border-radius:50%;
    background:rgba(201,163,78,.12);border:1px solid rgba(201,163,78,.5);color:var(--gold-deep);font-size:.92rem;
    animation:lockBreath 4.5s ease-in-out infinite;
    transition:background .35s var(--ease),color .35s var(--ease),border-color .35s var(--ease),box-shadow .35s var(--ease);
  }
  .kh-card:hover .kh-lock-badge{background:var(--gold);color:#12243f;border-color:var(--gold);box-shadow:0 0 18px rgba(201,163,78,.6)}
  body.lffo-member .kh-lock-badge{border-color:var(--leaf-green);color:var(--leaf-green);background:rgba(122,168,90,.12);animation:none}

  /* — library members cards keep their footer lock, given the same breathing
       gold treatment (no top badge — the card head is already occupied). */
  .lib-card .lib-lock{
    color:var(--gold-deep);
    animation:lockBreath 4.5s ease-in-out infinite;border-radius:4px;
  }

  /* — golden PERIMETER SHINE — ONLY on the members-only filter button. A more
       detailed comet: a bright white-gold hot core leads a long graduated gold
       tail, with a soft outer bloom (drop-shadow). It runs the border and
       returns seamlessly (registered-angle conic ring, so it never jumps at
       360°). overflow is opened so the ring is not clipped. */
  .kh-filter .khf-members,
  .lib-facets .lib-chip.spark-run,.lib-facets .lib-chip-mem{overflow:visible}
  .kh-filter .khf-members::before,
  .lib-facets .lib-chip.spark-run::before,.lib-facets .lib-chip-mem::before{
    content:"";position:absolute;inset:-1px;border-radius:inherit;pointer-events:none;z-index:2;
    padding:1.5px;
    background:conic-gradient(from var(--lffo-glow),
      transparent 0deg,transparent 242deg,
      rgba(201,163,78,.09) 280deg,
      rgba(201,163,78,.4) 322deg,
      var(--gold) 343deg,
      var(--gold-bright) 351deg,
      #fff7dd 356deg,
      var(--gold-bright) 359deg,
      transparent 360deg);
    -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
            mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
    -webkit-mask-composite:xor;mask-composite:exclude;
    filter:drop-shadow(0 0 3px rgba(220,183,99,.55));
    animation:lffoTravel 5.5s linear infinite;
    opacity:1;
  }
  .kh-filter .khf-members:hover::before,
  .lib-facets .lib-chip.spark-run:hover::before,.lib-facets .lib-chip-mem:hover::before{animation-duration:3s}
}
@keyframes lockBreath{
  0%,100%{box-shadow:0 0 0 rgba(201,163,78,0)}
  50%    {box-shadow:0 0 13px rgba(201,163,78,.42)}
}
@media (min-width:821px) and (prefers-reduced-motion:reduce){
  .kh-lock-badge,.lib-card .lib-lock{animation:none}
  .kh-filter .khf-members::before,
  .lib-facets .lib-chip.spark-run::before,.lib-facets .lib-chip-mem::before{animation:none;opacity:.5}
}
