/* The button system (Calvin, 4 Nov, on buttons/r2/: "let's go pass -- but on primary, no cursor switch to @ / secondary
   -- no flip, get's the cursor switch (not just @, but like in handoff (all hi-vis lime) / tertiary -- flip, no cursor
   switch / when I say no cursor switch, I mean not to one of the special @s or arrows, the switch signaling clickable is
   still good"; system A, "yours as proposed").
     primary    the Key with K1 · Pass: Geist Mono caps in an outlined pill and a round key in Trash's lit green that
                carries the signal (→ a page, ↗ a new tab, @ the email); on hover the glyph goes out the far side as its
                copy comes in. Plain pointer, the copy Key's too. Only the primary is ever a Key; one per section; the
                row starts on it (Calvin, 4 Nov: "primary buttons should be before secondary").
     secondary  the Line: Geist words on a hairline; no flip; the pointer becomes the action's glyph in hi-vis lime
     tertiary   the simple capsule, no fill; flips like the menu words; plain pointer
     quiet      the footer's links (.bs-q): no flip, no motion; slightly see-through at rest, full white on hover
                (Calvin, 4 Nov: "footer buttons -- no scramble -- let's make that a 4th option"); plain pointer, a
                copy link keeps the lime @
     links      inline (underlined, no motion), standalone (mono caps, flipping), footer and site map (the menu's words)
   Built from buttons/r2/ (key.css's base and K1, links.css, sa.css), with Calvin's cursor rules; buttons.js draws the
   secondary's pointer, flip.js (the board's steady-width copy of sparks.js) flips the tertiary and standalone links
   (data-flip-host on the link, data-flip on its .bs-t). menu.js keeps the copy itself (chip, Email copied) and draws the
   lime @ over copy links, except on primaries and tertiaries.
   Scope: class="bk k1 bl sa" on <body>. Markup:
     <div class="bs-acts">
       <a class="bs-b bs-b--pri" href="mailto:…" data-copy="…"><span class="bs-t">Work with us</span><span class="bs-i" aria-hidden="true"></span></a>
       <a class="bs-b bs-b--sec" href="…"><span class="bs-t">See the work</span><span class="bs-i" aria-hidden="true"></span></a>
     </div> */

/* ======== the Key (buttons/r2/key.css: its base, then K1 · Pass) ======== */
.bk {
  --bk-h: 46px;
  --bk-gap: 4px;                           /* between the pill and the key */
  --bk-g: 14px;                            /* the key's glyph */
  --bk-key: var(--green, #1ED68A);         /* Trash Green, lit: never #00A651 on black (the green is still Calvin's open call) */
  --bk-on-key: var(--on-green, #000000);
  --bk-edge: var(--edge, #3A3A3A);         /* the dock chips' edge */
  --bk-edge-hi: var(--gravel, #8C8C8C);
  --bk-focus: var(--lime, #D4F073);
  --bk-m: 1;
  --bk-beat: .32s;
  --bk-ease: cubic-bezier(.2, .8, .2, 1);
  --bk-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.5'%3E%3Cpath d='M1.5 8h12M8.5 3l5 5-5 5'/%3E%3C/svg%3E");
  --bk-ext: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6'%3E%3Cpath d='M3.5 12.5l9-9M5.5 3.5h7v7'/%3E%3C/svg%3E");
  --bk-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6'%3E%3Cpath d='M2.5 8.5l3.5 3.5 7.5-8'/%3E%3C/svg%3E");
  --bk-spin: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.5'%3E%3Cpath d='M8 1.75a6.25 6.25 0 1 1-6.25 6.25'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: reduce) { .bk { --bk-m: 0; } }
.rm .bk, .bk.rm { --bk-m: 0; }   /* the board's reduced-motion switch */

/* ---------- the Key at rest: the pill and the key ---------- */
.bk .bs-b--pri { --bk-r: calc(var(--bk-h) / 2); --bk-run: calc(var(--bk-h) * .8);
                 position: relative; display: inline-flex; align-items: stretch; gap: var(--bk-gap); box-sizing: border-box; height: var(--bk-h); border-radius: var(--bk-r);
                 color: var(--ink); text-decoration: none; white-space: nowrap; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.bk .bs-b--pri .bs-t { display: inline-flex; align-items: center; padding: 0 20px 0 21px; border-radius: var(--bk-r); box-shadow: inset 0 0 0 1px var(--bk-edge);
                       font: 400 12px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase;
                       transition: box-shadow calc(var(--bk-beat) * var(--bk-m)) var(--bk-ease), color calc(var(--bk-beat) * var(--bk-m)) var(--bk-ease); }
.bk .bs-b--pri .bs-i { position: relative; flex: none; width: var(--bk-h); border-radius: 50%; background: var(--bk-key); color: var(--bk-on-key); overflow: hidden; isolation: isolate;
                       transition: transform calc(var(--bk-beat) * var(--bk-m)) var(--bk-ease); }
/* the glyph (::before), and a second layer a motion may use (::after) */
.bk .bs-b--pri .bs-i::before, .bk .bs-b--pri .bs-i::after { content: ""; position: absolute; inset: 0; box-sizing: border-box; background: currentColor;
                       -webkit-mask: var(--bk-arrow) center / var(--bk-g) var(--bk-g) no-repeat; mask: var(--bk-arrow) center / var(--bk-g) var(--bk-g) no-repeat;
                       transition: transform calc(var(--bk-beat) * var(--bk-m)) var(--bk-ease), opacity calc(var(--bk-beat) * var(--bk-m)) var(--bk-ease); }
.bk .bs-b--pri .bs-i::after { content: none; }
.bk .bs-b--pri:is([target="_blank"], .bs-b--ext) .bs-i::before { -webkit-mask-image: var(--bk-ext); mask-image: var(--bk-ext); }
/* the email's key carries Geist's own @, the pointer's glyph */
.bk .bs-b--pri:is([data-copy], .bs-b--copy) .bs-i::before { content: "@"; display: grid; place-items: center; padding-bottom: 2px; background: none; -webkit-mask: none; mask: none;
                       font: 500 17px/1 var(--font-body); }

/* ---------- every motion shares these ---------- */
/* The primary keeps the plain pointer, the copy Key included (Calvin, 4 Nov: "on primary, no cursor switch to @"), so
   its @ passes through the key like any other glyph and the pill's edge lights with it. */
.bk .bs-b--pri:is(:hover, :focus-visible, .is-hover, .is-focus, .is-mid) .bs-t { box-shadow: inset 0 0 0 1px var(--bk-edge-hi); }
.bk .bs-b--pri:is(:focus-visible, .is-focus) { outline: 2px solid var(--bk-focus); outline-offset: 3px; }
.bk .bs-b--pri:is(:active, .is-press) .bs-i { transform: scale(.92); transition-duration: calc(.1s * var(--bk-m)); }

/* disabled: no green, both pieces on the page's hairline */
.bk .bs-b--pri[aria-disabled="true"] { pointer-events: none; cursor: default; color: color-mix(in srgb, var(--ink) 30%, transparent); }
.bk .bs-b--pri[aria-disabled="true"] .bs-t { box-shadow: inset 0 0 0 1px var(--hairline); }
.bk .bs-b--pri[aria-disabled="true"] .bs-i { background: none; color: inherit; box-shadow: inset 0 0 0 1px var(--hairline); }

/* busy (a form's send; the homepage's never wait): the key turns, at the Growth panel's spinner pace */
.bk .bs-b--pri[aria-busy="true"] { pointer-events: none; cursor: progress; }
.bk .bs-b--pri[aria-busy="true"] .bs-i::before { content: ""; display: block; padding: 0; background: currentColor; opacity: 1; transform: none;
                       -webkit-mask: var(--bk-spin) center / var(--bk-g) var(--bk-g) no-repeat; mask: var(--bk-spin) center / var(--bk-g) var(--bk-g) no-repeat;
                       animation: bk-spin .8s linear infinite; }
.bk .bs-b--pri[aria-busy="true"] .bs-i::after { content: none; }
@keyframes bk-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .bk .bs-b--pri[aria-busy="true"] .bs-i::before { animation: none; } }
.rm .bk .bs-b--pri[aria-busy="true"] .bs-i::before { animation: none; }

/* copied (menu.js's .is-copied, 1.6 s): a tick in the key; each motion says how it lands */
.bk .bs-b--pri:is([data-copy], .bs-b--copy).is-copied .bs-i::before { content: ""; display: block; padding: 0; background: currentColor; opacity: 1; transform: none;
                       -webkit-mask: var(--bk-check) center / var(--bk-g) var(--bk-g) no-repeat; mask: var(--bk-check) center / var(--bk-g) var(--bk-g) no-repeat; }

/* small: in a card, at the dock chips' height */
.bk .bs-b--pri.bs-b--s { --bk-h: 34px; --bk-g: 11px; --bk-gap: 3px; }
.bk .bs-b--pri.bs-b--s .bs-t { padding: 0 14px 0 15px; font-size: 11px; }
.bk .bs-b--pri.bs-b--s:is([data-copy], .bs-b--copy) .bs-i::before { font-size: 14px; }

/* phones: the Key takes the column, the words at the left and the key at the end */
@media (max-width: 600px) {
  .bk .bs-acts:not(.bs-acts--s) > .bs-b--pri { --bk-h: 50px; width: 100%; }
  .bk .bs-acts:not(.bs-acts--s) > .bs-b--pri .bs-t { flex: 1 1 auto; }
}


/* ==================== K1 · Pass: the glyph goes through the key ==================== */
.k1 .bs-b--pri .bs-i::after { content: ""; transform: translateX(calc(var(--bk-run) * -1)); }
.k1 .bs-b--pri:is([target="_blank"], .bs-b--ext) .bs-i::after { -webkit-mask-image: var(--bk-ext); mask-image: var(--bk-ext); transform: translate(calc(var(--bk-run) * -1), var(--bk-run)); }
.k1 .bs-b--pri:is([data-copy], .bs-b--copy) .bs-i::after { content: "@"; display: grid; place-items: center; padding-bottom: 2px; background: none; -webkit-mask: none; mask: none;
                       font: 500 17px/1 var(--font-body); }
.k1 .bs-b--pri.bs-b--s:is([data-copy], .bs-b--copy) .bs-i::after { font-size: 14px; }
.k1 .bs-b--pri:is(:hover, :focus-visible, .is-hover, .is-focus) .bs-i::before { transform: translateX(var(--bk-run)); }
.k1 .bs-b--pri:is(:hover, :focus-visible, .is-hover, .is-focus) .bs-i::after { transform: none; }
.k1 .bs-b--pri:is([target="_blank"], .bs-b--ext):is(:hover, :focus-visible, .is-hover, .is-focus) .bs-i::before { transform: translate(var(--bk-run), calc(var(--bk-run) * -1)); }
.k1 .bs-b--pri.is-mid .bs-i::before { transform: translateX(calc(var(--bk-run) * .3)); transition: none; }
.k1 .bs-b--pri.is-mid .bs-i::after { transform: translateX(calc(var(--bk-run) * -.7)); transition: none; }
.k1 .bs-b--pri:is([target="_blank"], .bs-b--ext).is-mid .bs-i::before { transform: translate(calc(var(--bk-run) * .3), calc(var(--bk-run) * -.3)); }
.k1 .bs-b--pri:is([target="_blank"], .bs-b--ext).is-mid .bs-i::after { transform: translate(calc(var(--bk-run) * -.7), calc(var(--bk-run) * .7)); }
/* copied: the @ passes out and the tick passes in */
.k1 .bs-b--pri:is([data-copy], .bs-b--copy).is-copied .bs-i::before { content: "@"; display: grid; place-items: center; padding-bottom: 2px; background: none; -webkit-mask: none; mask: none;
                       font: 500 17px/1 var(--font-body); animation: k1-out calc(var(--bk-beat) * var(--bk-m)) var(--bk-ease) both; }
.k1 .bs-b--pri:is([data-copy], .bs-b--copy).is-copied .bs-i::after { content: ""; display: block; padding: 0; background: currentColor;
                       -webkit-mask: var(--bk-check) center / var(--bk-g) var(--bk-g) no-repeat; mask: var(--bk-check) center / var(--bk-g) var(--bk-g) no-repeat;
                       animation: k1-in calc(var(--bk-beat) * var(--bk-m)) var(--bk-ease) both; }
@keyframes k1-out { from { transform: none; } to { transform: translateX(var(--bk-run)); } }
@keyframes k1-in { from { transform: translateX(calc(var(--bk-run) * -1)); } to { transform: none; } }



/* ======== links and the signal (buttons/r2/links.css) ======== */
/* Links, and the signal every non-primary tier carries. The same in all three systems (A, B, C): they differ only in
   the secondary and tertiary buttons (sa.css, sb.css, sc.css). Scope: .bl on an ancestor, with the system's class.
   - INLINE links in prose (Thoughts, case studies): the Thoughts manifesto's own rule, white and underlined at 1 px,
     2 px on hover, no motion; ↗ after one that opens a new tab; a copy link (the address) adds nothing, the @ is in it.
   - STANDALONE links ("See all work"): Geist Mono caps and the signal, in Gravel, flipping like the menu words.
   - FOOTER and SITE-MAP links: the menu's own words, Geist 15 px in Silver, flipping like the menu words.
   - The MENU itself: unchanged (menu.css, sparks.js).
   - COPY links ([data-copy], anywhere): menu.js as it is, the Copy email chip, the @ pointer, Email copied.
   The flip is flip.js (the board's steady-width copy of sparks.js): data-flip on the words, data-flip-host on the link.
   PORT: with key.css and the system's file. .is-hover / .is-focus / .is-press / .bs-b--ext / .bs-b--copy draw the
   board's held specimens only. */
.bl {
  --bl-m: 1;
  --bl-beat: .3s;
  --bl-ease: cubic-bezier(.2, .8, .2, 1);
  --bl-focus: var(--lime, #D4F073);        /* hi-vis: the focus ring, and nothing else */
  --bl-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.5'%3E%3Cpath d='M1.5 8h12M8.5 3l5 5-5 5'/%3E%3C/svg%3E");
  --bl-ext: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6'%3E%3Cpath d='M3.5 12.5l9-9M5.5 3.5h7v7'/%3E%3C/svg%3E");
  --bl-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6'%3E%3Cpath d='M2.5 8.5l3.5 3.5 7.5-8'/%3E%3C/svg%3E");
  --bl-spin: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6'%3E%3Cpath d='M8 1.75a6.25 6.25 0 1 1-6.25 6.25'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: reduce) { .bl { --bl-m: 0; } }
.rm .bl, .bl.rm { --bl-m: 0; }

/* ---------- the signal on secondary, tertiary and standalone links: → a page, ↗ a new tab, @ the email, ✓ copied ---------- */
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l) .bs-i { flex: none; width: .72em; height: .72em; background: currentColor;
             -webkit-mask: var(--bl-arrow) center / contain no-repeat; mask: var(--bl-arrow) center / contain no-repeat;
             transition: transform calc(var(--bl-beat) * var(--bl-m)) var(--bl-ease), opacity calc(var(--bl-beat) * var(--bl-m)) var(--bl-ease); }
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l):is([target="_blank"], .bs-b--ext) .bs-i { width: .62em; height: .62em; -webkit-mask-image: var(--bl-ext); mask-image: var(--bl-ext); }
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l):is([data-copy], .bs-b--copy) .bs-i { width: auto; height: auto; background: none; -webkit-mask: none; mask: none; }
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l):is([data-copy], .bs-b--copy) .bs-i::before { content: "@"; display: block; line-height: 1; }
/* hover and focus: the signal steps on, on the flip's beat */
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l):is(:hover, :focus-visible, .is-hover, .is-focus) .bs-i { transform: translateX(.16em); }
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l):is([target="_blank"], .bs-b--ext):is(:hover, :focus-visible, .is-hover, .is-focus) .bs-i { transform: translate(.1em, -.1em); }
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l):is([data-copy], .bs-b--copy):is(:hover, :focus-visible, .is-hover, .is-focus) .bs-i { transform: none; }
/* A COPY NEVER MOVES ON HOVER (Calvin, 4 Nov): no flip, no step; the pointer turning into the lime @ is its hover. Its @
   steps aside at once while the pointer carries it (a keyboard or a finger keeps it), and its colour changes at once */
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l):is([data-copy], .bs-b--copy), .bl :is(.bs-b--sec, .bs-b--ter, .bs-l):is([data-copy], .bs-b--copy) .bs-i { transition: none; }
/* (the tertiary keeps the plain pointer, so its @ stays: Calvin, 4 Nov, "tertiary -- flip, no cursor switch") */
@media (hover: hover) { .bl :is(.bs-b--sec, .bs-l):is([data-copy], .bs-b--copy):is(:hover, .is-hover) .bs-i { opacity: 0; } }
/* copied: a tick where the @ was */
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l):is([data-copy], .bs-b--copy).is-copied .bs-i { width: .72em; height: .72em; opacity: 1; background: currentColor;
             -webkit-mask: var(--bl-check) center / contain no-repeat; mask: var(--bl-check) center / contain no-repeat; }
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l):is([data-copy], .bs-b--copy).is-copied .bs-i::before { content: none; }
/* busy: the signal turns (the Growth panel's spinner, at its pace) */
.bl :is(.bs-b--sec, .bs-b--ter)[aria-busy="true"] { pointer-events: none; cursor: progress; }
.bl :is(.bs-b--sec, .bs-b--ter)[aria-busy="true"] .bs-i { width: .72em; height: .72em; transform: none; background: currentColor;
             -webkit-mask: var(--bl-spin) center / contain no-repeat; mask: var(--bl-spin) center / contain no-repeat; animation: bl-spin .8s linear infinite; }
.bl :is(.bs-b--sec, .bs-b--ter)[aria-busy="true"] .bs-i::before { content: none; }
@keyframes bl-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .bl :is(.bs-b--sec, .bs-b--ter)[aria-busy="true"] .bs-i { animation: none; } }
.rm .bl :is(.bs-b--sec, .bs-b--ter)[aria-busy="true"] .bs-i { animation: none; }
/* disabled, any tier: 30% ink, no events */
.bl :is(.bs-b--sec, .bs-b--ter, .bs-l)[aria-disabled="true"] { pointer-events: none; cursor: default; color: color-mix(in srgb, var(--ink) 30%, transparent); }

/* ---------- STANDALONE links: "See all work", Geist Mono caps and the signal ---------- */
.bl .bs-l { position: relative; display: inline-flex; align-items: center; gap: 8px; box-sizing: border-box; min-height: 36px; color: var(--gravel); cursor: pointer;
            font: 400 12px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; text-decoration: none; white-space: nowrap; -webkit-tap-highlight-color: transparent;
            transition: color calc(var(--bl-beat) * var(--bl-m)) var(--bl-ease); }
.bl .bs-l .bs-i { width: 10px; height: 10px; }
.bl .bs-l:is([target="_blank"], .bs-b--ext) .bs-i { width: 9px; height: 9px; }
.bl .bs-l:is(:hover, :focus-visible, .is-hover, .is-focus) { color: var(--ink); }
.bl .bs-l:is(:active, .is-press) { opacity: .62; }
.bl .bs-l:is(:focus-visible, .is-focus) { outline: 2px solid var(--bl-focus); outline-offset: 3px; border-radius: 2px; }

/* ---------- INLINE links in prose: the Thoughts manifesto's rule, no motion ---------- */
.bl .bs-prose a { color: var(--ink-hi); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.bl .bs-prose a:is(:hover, .is-hover) { text-decoration-thickness: 2px; }
.bl .bs-prose a:is(:focus-visible, .is-focus) { outline: 2px solid var(--bl-focus); outline-offset: 2px; border-radius: 2px; }
.bl .bs-prose a[target="_blank"]::after { content: ""; display: inline-block; width: .56em; height: .56em; margin-left: .14em; vertical-align: .06em; background: currentColor;
             -webkit-mask: var(--bl-ext) center / contain no-repeat; mask: var(--bl-ext) center / contain no-repeat; }

/* ---------- FOOTER and SITE-MAP links: the menu's words ---------- */
.bl .bs-nav { display: flex; flex-wrap: wrap; gap: 2px 28px; margin: 0; padding: 0; list-style: none; }
.bl .bs-nav a { position: relative; display: inline-block; padding: 9px 0; color: var(--ink-2); font: 400 15px/1 var(--font-body); letter-spacing: -.005em; text-decoration: none;
                -webkit-tap-highlight-color: transparent; }
.bl .bs-nav a:is(:hover, :focus-visible, .is-hover, .is-focus) { color: var(--ink-hi); }
.bl .bs-nav a:is(:focus-visible, .is-focus) { outline: 2px solid var(--bl-focus); outline-offset: 3px; border-radius: 2px; }

/* reduced motion: still states, no flip (flip.js checks) */
@media (prefers-reduced-motion: reduce) { .bl :is(.bs-b--sec, .bs-b--ter, .bs-l, .bs-l .bs-i, .bs-b--sec .bs-i, .bs-b--ter .bs-i) { transition: none !important; } }
.rm .bl :is(.bs-b--sec, .bs-b--ter, .bs-l, .bs-l .bs-i, .bs-b--sec .bs-i, .bs-b--ter .bs-i) { transition: none !important; }

/* ======== system A: the Line and the capsule (buttons/r2/sa.css) ======== */
/* SYSTEM A · Calvin's (4 Nov: "maybe the line as secondary. though I hate the underline animation -- would rather use the
   same text flip that we're using in menu. simple capsule (no white fill) as tertiary?"). Built as he said it:
     primary    the Key (key.css)
     secondary  round 1's 01 Line: Geist words on a hairline. No flip (Calvin, 4 Nov: "secondary -- no flip, get's the
                cursor switch (not just @, but like in handoff (all hi-vis lime)"): the pointer becomes the action's
                glyph in hi-vis lime (buttons.js; the @ is menu.js's) while the words and the hairline turn white
     tertiary   round 2's simple capsule: round 1's 02 glass capsule with its Concrete hairline and no fill. It flips
                like the menu words (flip.js) with the plain pointer ("tertiary -- flip, no cursor switch")
     links      links.css, the same in every system
   A copy never moves on hover (Calvin, 4 Nov): no flip; the pointer turning into the lime @ is its hover.
   PORT: key.css + links.css + this file. Scope: class="bk k1 bl sa" on <main>. */
.sa { --sa-rule: color-mix(in srgb, var(--gravel, #8C8C8C) 62%, var(--black, #000000)); }   /* the Line's hairline, between Edge and Gravel */

/* the row: the Key first, then the rest (Calvin, 4 Nov: "primary buttons should be before secondary"); a third action goes on its own line */
.sa .bs-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 32px; margin-top: 38px; }
.sa .bs-acts--s { gap: 6px 22px; margin-top: 20px; }

/* ---------- SECONDARY · the Line ---------- */
.sa .bs-b--sec { position: relative; display: inline-flex; align-items: center; gap: .34em; box-sizing: border-box; min-height: 46px; padding: 9px 0 12px;
                 color: var(--ink); font: 400 clamp(17px, 1.3vw, 19px)/1.2 var(--font-body); letter-spacing: -.01em; text-decoration: none; white-space: nowrap;
                 cursor: pointer; -webkit-tap-highlight-color: transparent; }
.sa .bs-b--sec::after { content: ""; position: absolute; left: 0; right: 0; bottom: 10px; height: 1px; background: var(--sa-rule); pointer-events: none; }
/* hover and focus: the words turn white and the hairline is white with them, at once; no flip, no draw */
.sa .bs-b--sec:is(:hover, :focus-visible, .is-hover, .is-focus) { color: var(--ink-hi); }
.sa .bs-b--sec:is(:hover, :focus-visible, .is-hover, .is-focus)::after { background: var(--ink-hi); }
.sa .bs-b--sec:is(:focus-visible, .is-focus) { outline: 2px solid var(--bl-focus); outline-offset: 5px; border-radius: 3px; }
.sa .bs-b--sec:is(:active, .is-press) .bs-t { opacity: .62; }
.sa .bs-b--sec:is(:active, .is-press)::after { height: 2px; }
.sa .bs-b--sec[aria-disabled="true"]::after { background: var(--hairline); }
.sa .bs-b--sec.bs-b--s { min-height: 38px; padding: 7px 0 10px; font-size: 15px; letter-spacing: -.005em; }
.sa .bs-b--sec.bs-b--s::after { bottom: 8px; }

/* ---------- TERTIARY · the simple capsule: glass and its hairline, no fill ---------- */
.sa .bs-b--ter { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 7px; box-sizing: border-box; height: 40px; padding: 0 18px;
                 border-radius: 999px; background: color-mix(in srgb, var(--asphalt, #171717) 86%, transparent); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
                 box-shadow: inset 0 0 0 1px var(--concrete); color: var(--ink); font: 400 14px/1 var(--font-body); letter-spacing: -.005em; text-decoration: none; white-space: nowrap;
                 cursor: pointer; -webkit-tap-highlight-color: transparent;
                 transition: box-shadow calc(.28s * var(--bl-m)) var(--bl-ease), background-color calc(.28s * var(--bl-m)) var(--bl-ease), transform calc(.12s * var(--bl-m)) var(--bl-ease); }
.sa .bs-b--ter .bs-i { width: 11px; height: 11px; }
.sa .bs-b--ter:is([target="_blank"], .bs-b--ext) .bs-i { width: 10px; height: 10px; }
.sa .bs-b--ter:is(:hover, :focus-visible, .is-hover, .is-focus) { background: var(--asphalt); box-shadow: inset 0 0 0 1px var(--gravel); }
.sa .bs-b--ter:is(:focus-visible, .is-focus) { outline: 2px solid var(--bl-focus); outline-offset: 3px; }
.sa .bs-b--ter:is(:active, .is-press) { transform: scale(.965); background: var(--concrete); }
.sa .bs-b--ter[aria-disabled="true"] { background: none; box-shadow: inset 0 0 0 1px var(--hairline); }
.sa .bs-b--ter.bs-b--s { height: 32px; padding: 0 13px; gap: 6px; font-size: 13px; }
.sa .bs-b--ter.bs-b--s .bs-i { width: 10px; height: 10px; }

/* phones: the Key takes the column (key.css) and comes first; the Line stays words at the left under it */
@media (max-width: 600px) { .sa .bs-acts:not(.bs-acts--s) { gap: 10px 28px; margin-top: 32px; } }
@media (prefers-reduced-motion: reduce) { .sa .bs-b--ter:is(:active, .is-press) { transform: none; } }
.rm .sa .bs-b--ter:is(:active, .is-press) { transform: none; }

/* ---------- the secondary's pointer (buttons.js): the action's own glyph in hi-vis lime, with the @'s dark halo ----------
   Calvin, 4 Nov: "secondary ... gets the cursor switch (not just @, but like in handoff (all hi-vis lime)". Over a
   secondary the pointer becomes → (a page) or ↗ (a new tab), drawn at the pointer as menu.js draws the @ over a copy
   secondary, and the Line's own signal steps aside while the pointer carries it (.is-carried). Pointers only. */
.bl .bs-b--sec.is-carried .bs-i { opacity: 0; transition: none; }
.glyph-cursor { position: fixed; left: 0; top: 0; z-index: 95; width: 40px; height: 40px; margin: -20px 0 0 -20px; display: grid; place-items: center; pointer-events: none;
                color: var(--lime, #D4F073); filter: drop-shadow(0 1px 8px rgba(0, 0, 0, .45)) drop-shadow(0 0 2px rgba(0, 0, 0, .45));
                opacity: 0; transform: translate(-999px, -999px); transition: opacity .18s ease; }
.glyph-cursor.is-on { opacity: 1; }
.glyph-cursor i { display: block; width: 22px; height: 22px; background: currentColor; transition: transform .1s ease;
                  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2'%3E%3Cpath d='M1.5 8h12M8.5 3l5 5-5 5'/%3E%3C/svg%3E") center / contain no-repeat;
                  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2'%3E%3Cpath d='M1.5 8h12M8.5 3l5 5-5 5'/%3E%3C/svg%3E") center / contain no-repeat; }
.glyph-cursor.is-ext i { width: 19px; height: 19px;
                  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2'%3E%3Cpath d='M3.5 12.5l9-9M5.5 3.5h7v7'/%3E%3C/svg%3E");
                  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2'%3E%3Cpath d='M3.5 12.5l9-9M5.5 3.5h7v7'/%3E%3C/svg%3E"); }
.glyph-cursor.is-down i { transform: scale(.84); }
@media (prefers-reduced-motion: reduce) { .glyph-cursor, .glyph-cursor i { transition: none; } }

/* ---------- 4 · QUIET: the footer's links (Calvin, 4 Nov: "footer buttons -- no scramble -- let's make that a 4th option.
   just goes from a slightly transparent to full white on hover (copy email cursor change stays)") ----------
   No flip and no motion: the words sit at 64% white and come up to full white on hover or focus. Plain pointer; a copy
   link (Contact, the address) keeps menu.js's lime @ and its chip. Markup: class="bs-q" on the link, no data-spark. */
.bl .bs-q { color: color-mix(in srgb, var(--ink-hi, #FFFFFF) 64%, transparent); transition: color calc(.2s * var(--bl-m)) ease; }
.bl .bs-q:is(:hover, :focus-visible, .is-hover, .is-focus) { color: var(--ink-hi, #FFFFFF); }
.bl .bs-q:is(:focus-visible, .is-focus) { outline: 2px solid var(--bl-focus); outline-offset: 3px; border-radius: 2px; }
