/* Avanza Up — avanzaup.com
   Inherited from avanzaprofit.com's system (Avanza/Site/src/style.css): the
   tokens, the type groups, the nav, the filled pill and the underline link are
   copied so the two sites read as one brand. NOT inherited: that site's page
   devices. This file is deliberately NOT a law yet — see README.md. */

:root{
  --bg:#ffffff; --panel:#ffffff;
  --ink:#000000;
  --line:rgba(0,0,0,.12); --line-strong:rgba(0,0,0,.2);
  --sage:#3c6b50; --sage-press:#2e5540;
  /* the one dark ground. Near-black on purpose: #000 stays reserved for type */
  --dark-ink:#14171a;
  /* form ghost text ONLY — every other glyph on the page is #000 */
  --ghost:#767676;
  /* one fluid UI step: nav, chips, lede and the underline link all sit here */
  --ui:clamp(14px, 0.3vw + 11px, 16px);
  --mp:'M PLUS Code Latin', ui-monospace, SFMono-Regular, Menlo, monospace;
  /* pill tints: fills for the four teaching areas, ICONS AND CHIPS only,
     never text colour. Each has its matching low-alpha border. */
  --green-bg:#ccdbc2;  --green-line:rgba(60,107,80,.42);
  --yellow-bg:#eadc8f; --yellow-line:rgba(122,106,42,.45);
  --blue-bg:#add9f4;   --blue-line:rgba(38,94,133,.40);
  --purple-bg:#e8c7de; --purple-line:rgba(154,88,126,.38);
  /* page measure + gutter, written once */
  --wrap:1240px;
  --pad:clamp(20px,4vw,44px);
  /* the one section gap. White -> white is one of these; a ground change pays
     two, because the section above and the section below each pay their own. */
  --sec:clamp(72px,10vh,124px);
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{ display:flex; flex-direction:column; min-height:100vh; background:var(--bg); color:var(--ink);
      font-family:'Work Sans',system-ui,sans-serif; -webkit-font-smoothing:antialiased; }
a{color:inherit;text-decoration:none}
button{font:inherit;background:none;border:none;cursor:pointer;color:inherit}
img{max-width:100%}

/* every nav item is an in-page anchor, so the whole page needs the offset the
   sticky nav eats — not just the two ids that happened to be linked. */
@media (prefers-reduced-motion:no-preference){ html{ scroll-behavior:smooth; } }
section[id], div[id]{ scroll-margin-top:80px; }

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001s !important; animation-iteration-count:1 !important}
  .btn-label, .btn-track, .btn-circle{ transition:none !important; transform:none !important; }
}

/* screen-reader-only */
.vh{ position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden;
     clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0; }

/* ================= type =================
   Organised by what a piece of text is FOR, not by its tag. Same six groups as
   avanzaprofit; a section picks a group and inherits, it never picks a size. */

/* A · statements — the line that carries a block's point. Claim 600, heads 500,
   one clamp shared so no two heads can drift apart. */
h1{ font:600 clamp(32px, 2.3vw + 2.3vh, 58px)/1.1 'Work Sans',sans-serif;
    letter-spacing:-.02em; margin:0; }
.route h2, .teach h2, .ws h2, .sup h2, .abt h2, .cta h2{
  font:500 clamp(32px, 2.3vw + 2.3vh, 58px)/1.1 'Work Sans',sans-serif;
  letter-spacing:-.02em; margin:0; }

/* B · item name — names one member of a repeating set */
.route-q, .teach-name, .ws-name, .sup-name, .brand-name{
  font:600 clamp(19px, .7vw + .9vh, 25px)/1.25 'Work Sans',sans-serif; margin:0; }

/* C1 · section thesis — the paragraph carrying a whole section */
.hero-lede, .route-lede, .teach-lede, .cta-lede{
  font:400 calc(var(--ui) * 1.6)/1.5 'Work Sans',sans-serif; margin:0; }

/* C2 · explanation — explains the thing directly above it */
.route-copy, .teach-copy, .ws-copy, .teach-note, .sup-note, .abt-copy p, .cform-note, .ws-count{
  font:400 calc(var(--ui) * 1.1)/1.6 'Work Sans',sans-serif; margin:0; text-wrap:pretty; }

/* D · labels — says what a block IS. Never a sentence, never clicked. */
.hero-kicker, .ft-h, .abt-role, .ws-filters-label{
  font:500 calc(var(--ui) * 1.1)/1.3 'Work Sans',sans-serif;
  letter-spacing:.06em; text-transform:uppercase; margin:0; }

/* E · action — you click it, something happens. The one mono use on the site. */
.btn-solid, .explore-link, .caps-cta, .ws-more, .cform button{
  font-family:var(--mp); font-size:.9em; letter-spacing:.09em; font-weight:600; }

/* F · interface — nav, chips, credentials, inputs. 500 names a thing, 400
   describes one. */
.nav-links > a, .ft-col a, .orgs-list li, .ft-id li, .cfield label, .ft-legal, .chip, .ws-tag{
  font:500 var(--ui)/1 'Work Sans',sans-serif; }

/* ================= nav =================
   Anchor nav: this is one page, so there is nothing to nest and no mega panel.
   Everything else is avanzaprofit's header verbatim. */
.nav{ position:sticky; top:0; z-index:50; flex:none; display:flex; align-items:center; gap:clamp(20px,3vw,40px);
      padding:13px var(--pad); background:#ffffff; border-bottom:1px solid var(--line); }
.nav-mark{ display:block; height:20px; width:auto; flex:none; color:#000000; }
.nav-links{ display:flex; align-items:center; justify-content:center; gap:clamp(16px,2vw,30px); flex:1; }
.nav-links > a{ color:var(--ink); padding:8px 0; white-space:nowrap; transition:color .18s ease; }
.nav-links > a:hover{ color:var(--sage); }
/* the section the reader is currently inside, written by app.js */
.nav-links > a[aria-current="true"]{ color:var(--sage); }
.nav-cta{ display:flex; align-items:center; gap:12px; flex:none; }

/* ---- the filled button: a pill with a travelling disc ----
   Label sits left with a white disc parked right; on hover they swap ends.
   GEOMETRY IS DERIVED: disc 36px in a 4px inset = a 44px pill, so padding-right
   is 4 + 36 + 12 = 52px and the label's travel is 52 - 22 = 30px. Change the
   disc or an inset and all three numbers move together. The disc's slide needs
   no knowledge of the button's width — .btn-track is the interior and moves
   -100%, the disc moves +100% of its own box, and the sum lands on 4px at every
   width. Transform and opacity only; never animate padding. */
.btn-solid{ position:relative; display:inline-flex; align-items:center; min-height:44px;
            padding:12px 52px 12px 22px; border-radius:999px; background:var(--sage); color:#ffffff;
            transition:background .2s linear; }
/* min-height, not height: the longest label on the site ("Bring Avanza Up to
   Your Organization") wraps to two lines inside a 390px column, and a fixed
   44px pill let the second line render outside its own background. The disc
   still centres itself because .btn-track is a centred flex over inset:4px. */
.btn-solid:hover{ background:var(--sage-press); }
.btn-label{ position:relative; z-index:1; line-height:1.3; transition:transform .45s cubic-bezier(.4,0,.2,1); }
.btn-solid:hover .btn-label{ transform:translateX(30px); }
.btn-track{ position:absolute; inset:4px; display:flex; align-items:center; justify-content:flex-end;
            pointer-events:none; transition:transform .45s cubic-bezier(.4,0,.2,1); }
.btn-solid:hover .btn-track{ transform:translateX(-100%); }
.btn-circle{ flex:none; display:flex; align-items:center; justify-content:center;
             width:36px; height:36px; border-radius:50%; background:var(--bg); color:var(--ink);
             transition:transform .45s cubic-bezier(.4,0,.2,1); }
.btn-solid:hover .btn-circle{ transform:translateX(100%) rotate(45deg); }
.btn-circle svg{ display:block; width:16px; height:16px; }

/* ---- the underline link, the site's second and last button type ---- */
.explore-link{ display:inline-flex; align-items:center; gap:8px; color:var(--ink);
               padding-bottom:2px; border-bottom:1px solid rgba(0,0,0,.35);
               transition:color .2s linear, border-color .2s linear; }
.explore-link:hover{ color:var(--sage); border-color:var(--sage); }
.explore-link .arrow{ transition:transform .2s ease; }
.explore-link:hover .arrow{ transform:translateX(3px); }
/* an arrow aimed at a section on this page travels along its own axis, not
   sideways like the ones that navigate away. --up is for a target ABOVE the
   link: About sits below the catalog it points back to. */
.explore-link .arrow--down, .explore-link .arrow--up{ transition:transform .2s ease; }
.explore-link:hover .arrow--down{ transform:translateY(3px); }
.explore-link:hover .arrow--up{ transform:translateY(-3px); }

/* ---- mobile ---- */
.nav-toggle{ display:none; flex:none; padding:8px; }
.nav-toggle span{ display:block; width:22px; height:2px; background:var(--ink); margin:5px 0; border-radius:2px; }
.mobile-panel{ display:none; position:fixed; inset:0; z-index:60; background:var(--bg);
               padding:20px clamp(20px,6vw,44px); overflow-y:auto; }
.mobile-panel.is-open{ display:block; }
.mobile-panel .mobile-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:28px; }
/* the mark is an <a> inside the panel, so it inherited the nav items' rule
   and rendered with a hairline under the logo. */
.mobile-head a{ padding:0; border-bottom:none; }
.mobile-panel a{ display:block; font:500 calc(var(--ui) * 1.4)/1 'Work Sans',sans-serif;
                 padding:14px 0; border-bottom:1px solid var(--line); }
.mobile-cta{ display:flex; flex-direction:column; gap:12px; margin-top:24px; }
/* .mobile-panel a beats .btn-solid on specificity, so the button's own box and
   group E's one size have to be restated here. */
.mobile-cta a{ display:flex; align-items:center; justify-content:flex-start;
               padding:12px 52px 12px 22px; border-bottom:none;
               font-family:var(--mp); font-size:.9em; }
@media (max-width:1080px){ .nav{ justify-content:space-between; } .nav-links{ display:none; }
                           .nav-cta{ display:none; } .nav-toggle{ display:block; } }

/* ================= hero =================
   Left-aligned, not centred: the claim is a statement of what the practice
   does, and there is no second column competing with it. */
.hero{ padding:clamp(64px,11vh,132px) var(--pad) clamp(52px,8vh,92px); }
.hero-inner{ max-width:var(--wrap); margin:0 auto; }
.hero-kicker{ color:#000000; margin-bottom:clamp(20px,2.6vh,30px); }
.hero h1{ max-width:17ch; text-wrap:balance; }
.hero-lede{ margin-top:clamp(20px,2.8vh,32px); max-width:58ch; }
.hero-actions{ display:flex; align-items:center; gap:clamp(20px,3vw,36px); flex-wrap:wrap;
               margin-top:clamp(30px,4.4vh,52px); }

/* ---- the audience bar, at the fold ----
   Not a logo wall: nothing is claimed here that the page cannot substantiate.
   It names the kinds of organization the practice works with, in the dot list
   the footer identity line also uses. */
.orgs{ flex:none; display:flex; align-items:center; justify-content:center; gap:9px;
       padding:16px var(--pad); background:#ffffff;
       border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.orgs-list{ margin:0; padding:0; list-style:none; display:flex; align-items:center;
            gap:30px; flex-wrap:wrap; justify-content:center; }
.orgs-list li{ position:relative; color:#000000; white-space:nowrap; }
.orgs-list li + li::before{ content:''; position:absolute; left:-16px; top:50%; width:3px; height:3px;
                            margin-top:-1.5px; border-radius:50%; background:rgba(0,0,0,.4); }

/* ================= routing: hands-on help =================
   Four cells, and the QUESTION is the name of each — this block's whole job is
   to let a visitor self-identify and leave for the right brand, so the reader's
   own situation is the label. Ruled cells, no shadows and no floating cards:
   the rules bleed to the page edges while the grid holds the 1240 measure, and
   that bleed is the only edge-to-edge line on the page. */
.route{ padding:var(--sec) 0; }
.route-head{ max-width:var(--wrap); margin:0 auto clamp(40px,5.5vh,64px); padding:0 var(--pad); text-align:center; }
.route-head h2{ max-width:24ch; margin:0 auto; text-wrap:balance; }
.route-lede{ margin-top:18px; max-width:56ch; margin-left:auto; margin-right:auto; text-wrap:pretty; }
.route-rail{ border-top:1px solid var(--line-strong); border-bottom:1px solid var(--line-strong); }
.route-grid{ max-width:var(--wrap); margin:0 auto; display:grid; grid-template-columns:1fr 1fr;
             border-left:1px solid var(--line); border-right:1px solid var(--line); }
.route-cell{ display:flex; flex-direction:column; align-items:flex-start;
             gap:14px; padding:clamp(28px,3.6vh,42px) clamp(24px,2.6vw,40px); }
.route-cell:nth-child(2n){ border-left:1px solid var(--line); }
.route-cell:nth-child(n+3){ border-top:1px solid var(--line); }
.route-copy{ max-width:44ch; }
/* 1fr on the copy pins every link to the bottom of its cell, so the four
   underlines line up across a row whatever the copy does. */
.route-copy{ flex:1; }
.route-cell .explore-link{ margin-top:4px; }

/* ================= what we teach =================
   A curriculum outline, so it is set as one: full-width rows with the area name
   in a fixed left column. Deliberately NOT four more cards — the block above is
   already a 2x2, and two grids of four in a row is the layout equivalent of
   saying the same thing twice. */
.teach{ padding:0 0 var(--sec); }
.teach-inner{ max-width:var(--wrap); margin:0 auto; padding:0 var(--pad); }
.teach-head{ margin-bottom:clamp(36px,5vh,56px); }
.teach-lede{ margin-top:18px; max-width:56ch; }
.teach-list{ display:grid; }
.teach-row{ display:grid; grid-template-columns:minmax(0,320px) minmax(0,1fr);
            gap:clamp(16px,3vw,56px); align-items:start;
            padding:clamp(24px,3.2vh,36px) 0; border-top:1px solid var(--line); }
.teach-row:last-of-type{ border-bottom:1px solid var(--line); }
.teach-copy{ max-width:62ch; }
.teach-note{ margin-top:clamp(28px,3.6vh,40px); max-width:70ch; }

/* ================= sample workshops =================
   A catalog, so it is set as a catalog: one ruled row per topic, filtered by
   the same four areas the section above names. The rhyme is the point — the
   areas are the taxonomy, and the chips prove it by working. */
.ws{ padding:0 0 var(--sec); }
.ws-inner{ max-width:var(--wrap); margin:0 auto; padding:0 var(--pad); }
.ws-head{ margin-bottom:clamp(28px,3.6vh,40px); }
.ws-filters{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
             margin-bottom:clamp(24px,3vh,32px); }
.ws-filters-label{ color:#000000; margin-right:6px; }
/* Active chip takes the filled button's sage, not a new colour: the two are the
   same gesture, "this one is on". */
.chip{ padding:9px 16px; border-radius:999px; border:1px solid var(--line-strong);
       background:#ffffff; color:var(--ink); white-space:nowrap;
       transition:background .18s ease, border-color .18s ease, color .18s ease; }
.chip:hover{ border-color:var(--sage); color:var(--sage); }
.chip[aria-pressed="true"]{ background:var(--sage); border-color:var(--sage); color:#ffffff; }
.ws-list{ display:grid; }
/* the tag column is capped, not `auto`: two long area names in one row would
   otherwise take whatever they needed and squeeze the topic title. */
.ws-row{ display:grid; grid-template-columns:minmax(0,1fr) minmax(200px,290px); gap:16px clamp(24px,3vw,48px);
         align-items:start; padding:clamp(20px,2.6vh,28px) 0; border-top:1px solid var(--line); }
/* :last-of-type ignores :not([hidden]), so the closing rule cannot be a
   selector — app.js marks the last VISIBLE row after every filter. */
.ws-row.is-last{ border-bottom:1px solid var(--line); }
/* an author `display` beats the UA sheet's [hidden]{display:none}, so a
   filtered-out row stays on the page unless this says otherwise. */
.ws-row[hidden], .ws-more[hidden]{ display:none; }
.ws-copy{ margin-top:8px; max-width:70ch; }
.ws-tags{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; justify-content:flex-end; }
/* The four area tints are fills. Food is a cross-cutting modifier, not a fifth
   area, so it is an outline chip — that difference is the information. */
.ws-tag{ padding:6px 13px; border-radius:999px; color:#000000; white-space:nowrap; }
.ws-tag--start{ background:var(--green-bg);  border:1px solid var(--green-line); }
.ws-tag--numbers{ background:var(--blue-bg);   border:1px solid var(--blue-line); }
.ws-tag--decisions{ background:var(--yellow-bg); border:1px solid var(--yellow-line); }
.ws-tag--running{ background:var(--purple-bg); border:1px solid var(--purple-line); }
.ws-tag--food{ background:#ffffff; border:1px solid var(--line-strong); }
.ws-foot{ display:flex; align-items:center; justify-content:space-between; gap:20px 32px;
          flex-wrap:wrap; margin-top:clamp(24px,3vh,32px); }
.ws-more{ display:inline-flex; align-items:center; gap:8px; padding-bottom:2px;
          border-bottom:1px solid rgba(0,0,0,.35); color:var(--ink);
          transition:color .2s linear, border-color .2s linear; }
.ws-more:hover{ color:var(--sage); border-bottom-color:var(--sage); }
.ws-count{ color:#000000; }

/* ================= ways we can support your program =================
   THE ONE DARK SECTION, and it gets the ground because it is the block that
   says what an organization can actually buy. Ground is --dark-ink, not #000:
   black stays reserved for type. --line-on is the inverted counterpart of
   --line and exists only inside this block. */
.sup{ --on:#ffffff; --line-on:rgba(255,255,255,.22);
      background:var(--dark-ink); color:var(--on); padding:var(--sec) 0; }
.sup-inner{ max-width:var(--wrap); margin:0 auto; padding:0 var(--pad); }
.sup-head{ margin-bottom:clamp(36px,5vh,56px); text-align:center; }
.sup h2{ color:var(--on); max-width:22ch; margin:0 auto; text-wrap:balance; }
.sup-grid{ display:grid; grid-template-columns:repeat(3,1fr);
           border-top:1px solid var(--line-on); border-left:1px solid var(--line-on); }
.sup-item{ padding:clamp(24px,3vh,34px) clamp(20px,2.2vw,32px);
           border-right:1px solid var(--line-on); border-bottom:1px solid var(--line-on); }
.sup-name{ color:var(--on); }
.sup-foot{ display:flex; align-items:center; justify-content:space-between; gap:24px 40px;
           flex-wrap:wrap; margin-top:clamp(36px,4.6vh,52px); }
.sup-note{ color:var(--on); max-width:62ch; }
.sup-note strong{ font-weight:600; }
/* the button keeps its sage on the dark ground — 4.1:1 against --dark-ink is
   the fill, and the label is #fff on sage at 6.16:1, unchanged from white. */

/* any section under the dark block pays its own top padding: .sup's bottom
   padding is dark pixels inside its own ground, so a white section that
   followed with padding-top:0 would sit flush against the dark edge. */
.sup + section{ padding-top:var(--sec); }

/* ================= about ================= */
.abt{ padding:0 0 var(--sec); }
.abt-inner{ max-width:var(--wrap); margin:0 auto; padding:0 var(--pad); }
.abt-grid{ display:grid; grid-template-columns:minmax(0,380px) minmax(0,1fr);
           gap:clamp(28px,4vw,72px); align-items:start; margin-top:clamp(36px,5vh,56px); }
.abt-photo{ display:block; width:100%; height:auto; border-radius:16px; }
.abt-role{ color:#000000; margin-top:20px; }
.abt-copy{ display:grid; gap:1.1em; max-width:66ch; }
.abt-copy strong{ font-weight:600; }
.abt-links{ display:flex; align-items:center; gap:clamp(20px,3vw,36px); flex-wrap:wrap; margin-top:8px; }

/* ================= closing: talk about your program =================
   The second and last non-white ground, and the ceiling. A third means
   re-planning the page. */
.cta{ --on:#ffffff; background:var(--sage); color:var(--on); padding:var(--sec) 0; }
.cta-inner{ max-width:var(--wrap); margin:0 auto; padding:0 var(--pad); }
.cta-head{ text-align:center; margin-bottom:clamp(36px,5vh,56px); }
.cta h2{ color:var(--on); max-width:22ch; margin:0 auto; text-wrap:balance; }
.cta-lede{ color:var(--on); margin:18px auto 0; max-width:52ch; text-wrap:pretty; }
/* the form sits on white inside the sage, so every input keeps the black ink
   and the hairlines it has everywhere else — no inverted form controls. */
/* One column, and the box holds the form only — an aside beside it made the
   white panel a second content block instead of the thing you fill in. The
   measure comes down with it: a single field spanning 1040px is a target you
   have to aim at. */
.cta-box{ max-width:760px; margin:0 auto;
          padding:clamp(28px,4vh,44px) clamp(24px,3vw,44px);
          background:#ffffff; color:var(--ink); border-radius:16px; }
.cform{ display:grid; gap:clamp(16px,2.2vh,22px); }
.cfield{ display:grid; gap:8px; }
.cfield label{ color:#000000; line-height:1.3; }
.cfield input, .cfield textarea{ width:100%; padding:13px 16px; border-radius:8px;
                                 border:1px solid var(--line-strong); background:#ffffff;
                                 font:400 var(--ui)/1.4 'Work Sans',sans-serif; color:var(--ink); }
.cfield input::placeholder, .cfield textarea::placeholder{ color:var(--ghost); }
.cfield textarea{ resize:vertical; min-height:130px; }
.cfield input:focus-visible, .cfield textarea:focus-visible{ outline:2px solid var(--sage); outline-offset:1px; }
.cform .btn-solid{ justify-self:start; }
.cform-note{ color:#000000; }
/* Honeypot. Off-screen rather than display:none — a bot that skips hidden
   fields still fills this one, which is the entire point. */
.hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }
/* submit states — the button keeps its box so the panel does not jump */
.cform.is-sending .btn-solid{ opacity:.6; pointer-events:none; }
.cform-note.is-error{ color:#8a2018; }
.cform-done{ display:grid; gap:10px; padding:clamp(20px,3vh,28px) 0; }
.cform-done h3{ margin:0; font:600 clamp(19px, .7vw + .9vh, 25px)/1.25 'Work Sans',sans-serif; }
.cform-done p{ margin:0; font:400 calc(var(--ui) * 1.1)/1.6 'Work Sans',sans-serif; text-wrap:pretty; }
.cform-note a{ border-bottom:1px solid rgba(0,0,0,.35);
               transition:color .18s ease, border-color .18s ease; }
.cform-note a:hover{ color:var(--sage); border-bottom-color:var(--sage); }

/* ================= footer =================
   Same ground as the page, separated by a hairline exactly as the nav is at the
   other end — one line, no slab of colour. */
.ft{ flex:none; background:#ffffff; border-top:1px solid var(--line);
     padding:clamp(48px,7vh,72px) var(--pad) clamp(28px,3vh,36px); }
.ft-inner{ max-width:var(--wrap); margin:0 auto; }
.ft-top{ display:grid; grid-template-columns:auto 1fr; gap:clamp(28px,3vw,60px); align-items:start; }
.ft-cols{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(24px,2.6vw,44px); }
.ft-mark{ display:block; color:#000000; }
.ft-mark svg{ display:block; height:20px; width:auto; }
.ft-h{ display:block; margin-bottom:16px; color:#000000; }
.ft-col ul{ margin:0; padding:0; list-style:none; display:grid; gap:11px; }
.ft-col a{ color:#000000; line-height:1.35; transition:color .18s ease; }
.ft-col a:hover{ color:var(--sage); }
.ft-bottom{ display:flex; align-items:center; justify-content:space-between; gap:20px 32px;
            flex-wrap:wrap; margin-top:clamp(40px,5vh,64px); padding-top:clamp(20px,2.4vh,26px);
            border-top:1px solid var(--line); }
.ft-id{ margin:0; padding:0; list-style:none; display:flex; align-items:center; gap:30px; flex-wrap:wrap; }
.ft-id li{ position:relative; color:#000000; white-space:nowrap; }
.ft-id li + li::before{ content:''; position:absolute; left:-16px; top:50%; width:3px; height:3px;
                        margin-top:-1.5px; border-radius:50%; background:rgba(0,0,0,.4); }
.ft-legal{ margin:0; color:#000000; }
.ft-legal a{ transition:color .18s ease; }
.ft-legal a:hover{ color:var(--sage); }

/* ================= narrow =================
   One block, at the foot, so a size is never overridden in three places. */
@media (max-width:900px){
  .route-grid{ grid-template-columns:1fr; }
  .route-cell:nth-child(2n){ border-left:none; }
  .route-cell + .route-cell{ border-top:1px solid var(--line); }
  .teach-row{ grid-template-columns:1fr; gap:10px; }
  .ws-row{ grid-template-columns:1fr; }
  .ws-tags{ justify-content:flex-start; }
  .sup-grid{ grid-template-columns:1fr 1fr; }
  .abt-grid{ grid-template-columns:1fr; }
  .abt-photo{ max-width:340px; }
}
@media (max-width:620px){
  .hero h1{ font-size:clamp(28px,7.4vw,38px); }
  /* the shared A clamp bottoms out at 32px, which breaks "hands-on" across the
     hyphen in a 350px column. One step down, still one rule for all six. */
  .route h2, .teach h2, .ws h2, .sup h2, .abt h2, .cta h2{ font-size:clamp(26px,6.6vw,34px); }
  /* a separator painted to the LEFT of its item lands at the start of a wrapped
     line. The bar wraps here, so the dots go and the gap does the separating. */
  .orgs-list li + li::before{ display:none; }
  /* six chips stacked one per line is 300px of filter above the thing being
     filtered. One scrolling row instead — the label stays in the DOM because
     the list is aria-labelledby it. */
  .ws-filters{ flex-wrap:nowrap; overflow-x:auto; overscroll-behavior-x:contain;
               padding-bottom:4px; -webkit-overflow-scrolling:touch; }
  .ws-filters .chip{ flex:none; }
  .ws-filters-label{ position:absolute; width:1px; height:1px; margin:-1px; padding:0;
                     overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; }
  .sup-grid{ grid-template-columns:1fr; }
  .ft-top{ grid-template-columns:1fr; }
  .ft-mark{ margin-bottom:8px; }
  .ft-cols{ grid-template-columns:1fr 1fr; gap:30px 24px; }
  .ft-bottom{ flex-direction:column; align-items:flex-start; }
  .orgs-list{ gap:10px 30px; }
}
