/* Generated by scripts/build-bisbe-kb.mjs — do not edit by hand. */
/* ── THE FACES ARE VENDORED, NEVER FETCHED FROM A THIRD PARTY, for the same reason the
   front door carries no Google <link> trio: a CDN
   stylesheet fetch carries the visitor's IP to fonts.googleapis.com before they have
   consented to anything. Same unmodified upstream latin-subset variable builds
   /styles.css already serves; the /fonts/ paths are root-absolute like every other
   reference on these pages. */
@font-face{font-family:'Familjen Grotesk';font-style:normal;font-weight:400 700;
  font-display:swap;src:url('/fonts/familjen-grotesk-latin-var.woff2') format('woff2')}
@font-face{font-family:'Familjen Grotesk';font-style:italic;font-weight:400 700;
  font-display:swap;src:url('/fonts/familjen-grotesk-italic-latin-var.woff2') format('woff2')}
@font-face{font-family:'Cinzel';font-style:normal;font-weight:400 900;
  font-display:swap;src:url('/fonts/cinzel-latin-var.woff2') format('woff2')}
/* ── THE BRAND, ON THE SURFACE — AND OFF THE GROUND (2026-08-13) ──────────────────
   Bisbe green used to appear in exactly one place on all 46 pages: the theme-color
   meta tag. A previous pass answered that by giving the GROUND a green cast
   (#F6F8F5) — and that cast sat on precisely the axis the sole ruling viewer cannot
   resolve: FOUNDER is red/green colourblind, and under both deuteranopia and
   protanopia a near-white whose blue channel is lowest reads as WARM CREAM — the
   CHANNEL ORDER is the rule (ΔE is the wrong instrument for near-whites, where JND
   spacing collapses); the measured collapse to ΔE 1.0 from #FBFAF8 was the evidence,
   #FBFAF8 being an enumerated member of the site-wide tan ban (AIU-STYLE-GUIDE §1,
   "LIKE EVERY OTHER CLAUDE BACKGROUND ON THE INTERNET"). The greenness that
   justified the hex was invisible to him by construction; only the banned residue
   reached him. He caught it on the Support page, 2026-08-13.
   THE GROUND IS THE COOL QUAD NOW — the same #FAFBFD family every front-door
   sibling and the style guide's §1 canon use, a lightness-matched swap (ΔE 2.86)
   nobody with normal vision will notice that flips the CVD residue from cream to
   cool. Identity keeps the green where the ban says it lives — IN DETAILS: heading
   ink, hairlines, and the row-wash as an ALPHA TINT of the brand green over the
   cool ground (the front door's own fulcrum idiom), never an opaque green-cast hex.

   COLOUR CARRIES NO MEANING HERE, and that is a rule rather than an accident. The
   current row is signalled by a filled left rail PLUS a lightness step, focus by a
   2px outline, a stale page by the words. Green is identity only, and it never
   appears opposite a red. */
:root{--green:#123B2E;--green-ink:#0E2F25;--green-wash:rgba(18,59,46,.05);
  --ink:#14171D;--dim:#4C5560;--paper:#FFFFFF;--g0:#FAFBFD;--g2:#F0F3F8;
  --line:rgba(18,59,46,.18);--gilt:#5C4108}
[data-theme="dark"]{--green:#8FBFA8;--green-ink:#A8CFBB;--green-wash:rgba(98,199,161,.07);
  --ink:#F2F4F8;--dim:#AFB8BF;--paper:#141923;--g0:#0E1116;--g2:#1B212C;
  --line:rgba(226,240,232,.16);--gilt:#C9A55A}
*{box-sizing:border-box}
body{margin:0;background:var(--g0);color:var(--ink);
  font-family:'Familjen Grotesk',system-ui,-apple-system,sans-serif;line-height:1.65}

/* ── THE ACCESSIBILITY FLOOR THAT WAS MISSING ─────────────────────────────────────
   This sheet declared no :focus-visible at all, so the whole surface leant on the
   browser's default ring over tinted rows, and no page had a skip link. Both are floor
   items rather than refinements, and a field at the top of the page makes both matter
   more. The skip link is ONE control, which is what keeps it clear of the anchor-jump
   ruling — that law is about MENUS of same-page links, and this is a single WCAG
   bypass. */
:focus-visible{outline:2px solid var(--green-ink);outline-offset:2px;border-radius:6px}
.skip{position:absolute;left:-9999px}
.skip:focus{left:14px;top:14px;z-index:9;background:var(--paper);border:1px solid var(--line);
  padding:11px 15px;border-radius:10px;text-decoration:none;font-size:15px}

.kb-bar{border-bottom:1px solid var(--line);background:var(--paper);position:sticky;top:0;z-index:5}
.kb-bar-in{max-width:78ch;margin:0 auto;padding:10px 22px;display:flex;align-items:center;
  gap:8px;flex-wrap:wrap}
/* ONE MARK PER PLACEMENT (FOUNDER, 2026-08-12: "no duplications of logo/name in one
   place"). This lockup was the B monogram with the word "Bisbe" beside it in Cinzel — the
   name once as artwork and once as type, in one control. The compact file IS the wordmark,
   so it is the whole lockup and the anchor's aria-label carries the accessible name.
   The reversed file is the correct mark on the dark ground: the monogram-only lockup was
   forest green (#123B2E) on --paper #1A1D24 in dark mode, i.e. all but invisible, and
   widening the same artwork would have widened the same fault. */
.kb-lockup{display:flex;align-items:center;min-height:44px;text-decoration:none;color:var(--ink)}
.kb-lockup img{height:22px;width:auto}
.kb-lockup .d{display:none}
[data-theme="dark"] .kb-lockup .l{display:none}
[data-theme="dark"] .kb-lockup .d{display:block}
.kb-nav{display:flex;align-items:center;gap:4px}
.kb-nav-a{display:inline-flex;align-items:center;min-height:44px;padding:0 12px;
  border-radius:10px;border:1px solid transparent;color:var(--dim);text-decoration:none;
  font-size:15px;font-weight:500}
.kb-nav-a:hover{color:var(--ink);background:var(--g2);border-color:var(--line)}
.kb-nav-a[aria-current="page"]{color:var(--ink);border-color:var(--ink)}
.kb-sp{flex:1 1 auto}
.kb-bar button{min-height:44px;padding:8px 12px;border:1px solid var(--line);border-radius:10px;
  background:none;color:var(--ink);font:inherit;font-size:14px;cursor:pointer}

/* ── ONE MEASURE WAS DOING TWO JOBS ───────────────────────────────────────────────
   74ch held the article prose AND the 44-row list, and was wrong for each in a
   different direction. The container goes to 78ch so the list gets width; the prose
   gets its own 66ch below, which is the one change a reader feels most and cannot
   name. Spacing is one scale — 8 · 14 · 22 · 34 · 52 — in place of the thirteen
   numbers that were doing five jobs. */
.kb-main{max-width:78ch;margin:0 auto;padding:34px 22px 84px}
h1{font-family:'Cinzel',Georgia,serif;font-size:clamp(30px,6vw,46px);line-height:1.06;
  letter-spacing:-.015em;margin:0 0 12px;color:var(--green-ink);text-wrap:balance}
.kb-sub{font-size:19px;line-height:1.55;color:var(--dim);margin:0 0 22px;max-width:52ch}
.kb-crumb{font-size:15px;color:var(--dim);margin:0 0 12px}
.kb-crumb a{text-decoration:none;border-bottom:1px solid var(--line);color:inherit}
/* A printed section mark — a short rule ABOVE the words — instead of the browser
   default underline below them. The count sits on the head because scope is status,
   and status belongs on the thing it describes. */
h2{font-family:'Cinzel',Georgia,serif;font-size:clamp(21px,2.6vw,26px);color:var(--green-ink);
  margin:0 0 14px;display:flex;flex-wrap:wrap;align-items:baseline;gap:0 12px}
/* The rule is a full-width flex item that PAINTS only its first 42px — one element, no
   extra markup, and it takes a row of its own so the words sit under it rather than
   beside it. */
h2::before{content:"";flex:0 0 100%;height:2px;margin:0 0 14px;
  background:linear-gradient(to right,var(--green) 0 42px,transparent 42px)}
h2 .cnt{margin-left:auto;font-size:13.5px;font-weight:400;color:var(--dim);
  font-family:'Familjen Grotesk',system-ui,sans-serif;font-variant-numeric:tabular-nums;
  white-space:nowrap}
p{font-size:17px;margin:0 0 14px}
a{color:inherit}
.kb-body p{font-size:17.5px;line-height:1.72;max-width:66ch}
.kb-cat{margin:0 0 52px}
.kb-sect{margin:52px 0 0}

/* ── THE ROWS ARE THE PAGE ────────────────────────────────────────────────────────
   So they step above body text, get real padding and a rail that fills under the
   pointer and under focus. The rail is a 3px border that is ALWAYS there and merely
   changes colour, so nothing moves. The preview is clamped to two lines: two of the 44
   run long enough to make their row twice the height of its neighbours. */
.kb-list{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.kb-list li{border-bottom:1px solid var(--line)}
.kb-list a{display:block;padding:15px 14px 15px 16px;text-decoration:none;min-height:44px;
  border-left:3px solid transparent;border-radius:0 10px 10px 0;
  transition:background 120ms ease,border-left-color 120ms ease}
.kb-list a:hover,.kb-list a:focus-visible{background:var(--green-wash);border-left-color:var(--green)}
.kb-list b{display:block;font-size:17px;font-weight:600;line-height:1.35}
.kb-list span{display:block;font-size:15.5px;color:var(--dim);margin-top:3px;line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.kb-receipt{border:1px solid var(--line);border-left:3px solid var(--gilt);border-radius:0 12px 12px 0;
  background:var(--paper);padding:15px 18px;margin:26px 0 0}
.kb-receipt p{margin:0;font-size:15px}
.kb-receipt .kb-r-meta{color:var(--dim)}
.kb-note{border:1px solid var(--line);border-radius:12px;background:var(--paper);
  padding:15px 18px;margin:22px 0}
.kb-note p:last-child{margin-bottom:0}
.kb-foot{border-top:1px solid var(--line);margin-top:52px;padding-top:22px}
.kb-foot p{font-size:15px;color:var(--dim)}
.kb-powered{font-size:15px}
.kb-foot-links{font-size:15px}
.kb-door{border:1px solid var(--line);border-left:3px solid var(--gilt);border-radius:0 12px 12px 0;
  background:var(--paper);padding:16px 18px;margin:22px 0}
.kb-door p:last-child{margin-bottom:0}

/* ── SEARCH · THE SLOT IS RESERVED BEFORE FIRST PAINT, AND ONLY IF A SCRIPT RAN ───
   The pre-paint snippet in every head sets data-js="on" — the same mechanism that stops
   the flash of the wrong theme. The height below is held ONLY under that attribute, so
   with script the field appears into space already reserved for it (no shift), and
   without script there is no reserved gap for a field that will never arrive (no hole).
   The two numbers are the injected control's real height: label 25 + gap 8 + field 52 on
   the index, and field 52 alone on an article page, where the label is visually hidden. */
#kb-find-slot{min-height:0}
[data-js="on"] #kb-find-slot{min-height:52px;margin:0 0 18px}
[data-js="on"] #kb-find-slot[data-labelled]{min-height:85px;margin:0 0 22px}
/* The two heights above are ARITHMETIC, not estimates, and the three rules below are what
   make them true regardless of which typeface has finished loading: the label's line box is
   set in px (25) rather than in a multiplier, and the field is a FIXED 52 rather than a
   minimum that the input's own line-height can push past. 25 + 8 + 52 = 85 on the index;
   52 on an article page, where the label is visually hidden. Measured after this change,
   both to the pixel. */
.kb-find-lab{display:block;font-size:15px;font-weight:600;line-height:25px;margin:0 0 8px}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.kb-find{display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:12px;
  background:var(--paper);padding:0 12px 0 14px;height:52px;
  transition:border-color 120ms ease,box-shadow 120ms ease}
.kb-find:focus-within{border-color:var(--green);box-shadow:0 0 0 3px var(--green-wash)}
.kb-find .gl{color:var(--dim);font-size:19px;line-height:1;flex:none}
/* NEVER below 16px: iOS zooms the whole page on focus of a smaller field, which is a jank
   bug wearing a type-size costume. */
.kb-find input{flex:1;min-width:0;border:0;background:none;color:var(--ink);font:inherit;
  font-size:16.5px;line-height:1.4;padding:0;outline:none;-webkit-appearance:none;appearance:none}
.kb-find input::placeholder{color:var(--dim)}
.kb-find input[type="search"]::-webkit-search-cancel-button,
.kb-find input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;display:none}
.kb-find .kbd{font-size:13.5px;color:var(--dim);border:1px solid var(--line);border-radius:6px;
  padding:2px 7px;flex:none}
@media (max-width:700px){.kb-find .kbd{display:none}}
.kb-find .clr{min-height:44px;min-width:44px;border:0;background:none;color:var(--dim);
  font:inherit;font-size:15px;cursor:pointer;border-radius:8px;flex:none}
.kb-find .clr:hover{color:var(--ink);background:var(--g2)}

/* Results are CONTENT, not chrome: no glass, no blur, no floating panel over the page.
   They are added above the list, never instead of it, and the rows are a fixed shape —
   title one line, lede clamped to two, meta one — so re-ranking on the next keystroke
   cannot re-flow the page under a reader's thumb. */
.kb-res{border:1px solid var(--line);border-left:3px solid var(--green);
  border-radius:0 14px 14px 0;background:var(--paper);padding:16px 18px;margin:0 0 30px}
/* No control renders live when the script that answers it has not arrived — the ship's own
   ruling for search, now applied to the theme toggle too (walker R5): with JS off the button
   was a visible dead control on all 46 pages. Same data-js flag, same honesty. */
html:not([data-js="on"]) [data-theme-toggle]{display:none}
.kb-res-h{display:flex;align-items:baseline;gap:14px;margin:0 0 4px;flex-wrap:wrap}
/* min-width:0 + overflow-wrap:anywhere — the count line echoes WHATEVER was typed (a pasted
   email, an 82-char URL, a ?q= someone shared); as a flex item its min-width:auto otherwise
   forbids breaking, and one unbroken token drags the entire page sideways at phone widths
   (walker R1, WITNESSED at 320-768: 182-2568px of horizontal scroll). */
.kb-res-h b{font-size:17px;font-weight:600;min-width:0;overflow-wrap:anywhere}
.kb-res-h .clear2{margin-left:auto;min-height:44px;padding:0 12px;border:1px solid var(--line);
  border-radius:9px;background:none;color:var(--ink);font:inherit;font-size:14.5px;cursor:pointer}
.kb-res-h .clear2:hover{background:var(--g2)}
.kb-res ul{list-style:none;margin:10px 0 0;padding:0}
.kb-res li{border-top:1px solid var(--line)}
.kb-res li:first-child{border-top:0}
/* ROWS ONLY. The one link that is not a row — the email address in the sentence under the
   empty state — stays inline prose; a block-level anchor there would break the sentence
   across three lines and turn a phrase into a control. */
.kb-res li a{display:block;padding:13px 12px 13px 14px;text-decoration:none;
  border-left:3px solid transparent;border-radius:0 10px 10px 0;min-height:44px;
  transition:background 120ms ease,border-left-color 120ms ease}
.kb-res li a:hover,.kb-res li a:focus-visible{background:var(--green-wash);border-left-color:var(--green)}
.kb-res p.door a{text-decoration:underline;text-underline-offset:2px}
/* Rows are a fixed shape (the direction doc's jank rule 2, now actually built — walker R2):
   title ONE line with ellipsis, lede clamped to two, meta ONE line — so a row's geometry
   never re-flows under the reader's thumb as ranking changes. */
.kb-res b.t{display:block;font-size:17px;font-weight:600;line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.kb-res span.l{display:block;font-size:15.5px;color:var(--dim);margin-top:3px;line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.kb-res span.met{display:block;font-size:13.5px;color:var(--dim);margin-top:5px;
  font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.kb-res .stale{border:1px solid var(--gilt);border-radius:6px;padding:1px 7px;font-size:13.5px;
  margin-left:8px;color:var(--gilt)}
/* A match is marked by lightness and an underline, never by a hue. */
.kb-res mark{background:var(--green-wash);color:inherit;box-shadow:inset 0 -2px 0 var(--green);
  border-radius:2px;padding:0 1px}
.kb-res p.said{font-size:15.5px;color:var(--dim);margin:6px 0 0;max-width:60ch}
.kb-res p.door{font-size:16px;margin:16px 0 0}
.kb-res h3{font-size:15px;font-weight:600;margin:18px 0 0}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
