/* Hallmark · macrostructure: Long Document · tone: austere editorial · anchor hue: navy · nav: N9 · footer: Ft1 · contrast: pass (40–41) · slop: pass (42–49) */
/* Hallmark · pre-emit critique: P5 H5 E4 S5 R5 V5 */
/* ONE TYPEFACE — Satoshi. Locked 2026-08-28 ("all satoshi"). Cuts must match
   scripts/lib/typography.mjs and --font-sans in src/styles/globals.css.
   The 300 cut is new here; Source Serif 4 was dropped (~122KB unused). */
@font-face{font-family:Satoshi;src:url('/fonts/Satoshi-300.woff2') format('woff2');font-weight:300;font-display:swap}@font-face{font-family:Satoshi;src:url('/fonts/Satoshi-400.woff2') format('woff2');font-weight:400;font-display:swap}@font-face{font-family:Satoshi;src:url('/fonts/Satoshi-500.woff2') format('woff2');font-weight:500;font-display:swap}@font-face{font-family:Satoshi;src:url('/fonts/Satoshi-700.woff2') format('woff2');font-weight:700;font-display:swap}
:root{
  --color-paper:oklch(97.7% .009 82);--color-paper-raised:oklch(99% .005 82);--color-paper-deep:oklch(95% .012 82);--color-ink:oklch(22% .035 255);--color-ink-strong:oklch(16% .05 255);--color-muted:oklch(48% .025 255);--color-faint:oklch(65% .018 255);--color-rule:oklch(88% .012 82);--color-rule-strong:oklch(74% .025 255);--color-accent:oklch(56% .12 70);--color-accent-ink:oklch(99% .005 82);--color-focus:oklch(56% .16 70);--color-warning:oklch(46% .105 70);--color-warning-paper:oklch(94% .035 82);
  --font-sans:'Satoshi','Helvetica Neue',Arial,sans-serif;--font-display:var(--font-sans);--font-body:var(--font-sans);
  --space-3xs:4px;--space-2xs:8px;--space-xs:12px;--space-sm:16px;--space-md:24px;--space-lg:32px;--space-xl:48px;--space-2xl:64px;--space-3xl:96px;--space-4xl:128px;
  --text-xs:.75rem;--text-sm:.875rem;--text-base:1rem;--text-md:1.125rem;--text-lg:1.5rem;--text-xl:2rem;--text-2xl:clamp(2.25rem,5vw,3.75rem);
  --ease-out:cubic-bezier(.22,1,.36,1);--dur-fast:120ms;--dur-base:180ms;--rule-hair:1px;--rule-strong:2px;--radius-control:8px;--radius-surface:12px;
}
*{box-sizing:border-box}html{background:var(--color-paper);color:var(--color-ink);overflow-x:clip}body{margin:0;font-family:var(--font-body);background:var(--color-paper);color:var(--color-ink)}a{color:inherit}img{display:block;max-width:100%}
.topbar{min-height:72px;padding:var(--space-sm) clamp(var(--space-sm),4vw,var(--space-xl));display:flex;align-items:center;justify-content:space-between;gap:var(--space-md);background:var(--color-paper)}
.brand,.footer__brand{font-family:var(--font-display);font-size:1.4rem;font-weight:500;letter-spacing:-.022em;text-decoration:none;white-space:nowrap}.topbar__cta,.primary{min-height:44px;display:inline-flex;align-items:center;justify-content:center;background:var(--color-ink-strong);color:var(--color-accent-ink);padding:var(--space-xs) var(--space-md);font-size:var(--text-sm);font-weight:700;text-decoration:none;white-space:nowrap;border:var(--rule-hair) solid var(--color-ink-strong);border-radius:var(--radius-control);transition:background-color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}
.topbar__cta:hover,.primary:hover{background:var(--color-muted);border-color:var(--color-muted)}.topbar__cta:focus-visible,.primary:focus-visible,.signin:focus-visible,.back-link:focus-visible,.section-head a:focus-visible,.report-row:focus-visible,.brand:focus-visible,.footer__brand:focus-visible{outline:3px solid var(--color-focus);outline-offset:3px}.topbar__cta:active,.primary:active{background:var(--color-ink)}.topbar__cta[aria-disabled=true],.primary[aria-disabled=true]{opacity:.55;cursor:not-allowed;pointer-events:none}
.report-shell{border-top:var(--rule-hair) solid var(--color-rule);padding:var(--space-xl) clamp(var(--space-sm),5vw,var(--space-2xl)) var(--space-3xl)}.reader{width:min(100%,920px);margin:0 auto;overflow-wrap:anywhere;min-width:0}.back-link{display:inline-block;margin-bottom:var(--space-lg);color:var(--color-muted);font-size:var(--text-sm);font-weight:500;text-underline-offset:4px}
.report-head{display:flex;align-items:center;gap:var(--space-md);padding-bottom:var(--space-md)}.company-mark{width:56px;height:56px;flex:0 0 56px;display:grid;place-items:center;background:var(--color-paper-raised);border:var(--rule-hair) solid var(--color-rule);border-radius:var(--radius-control);overflow:hidden}.company-mark img{width:42px;height:42px;object-fit:contain}.company-fallback{font-weight:700;letter-spacing:.04em;color:var(--color-ink)}.report-kind,.library-head>p:first-child{margin:0 0 var(--space-3xs);color:var(--color-accent);font-size:var(--text-xs);font-weight:700;letter-spacing:.14em;text-transform:uppercase}.report-head h1,.library-head h1{font-family:var(--font-display);font-weight:420;letter-spacing:-.035em;line-height:1.02;overflow-wrap:anywhere;min-width:0}.report-head h1{font-size:var(--text-2xl);margin:0}.report-head h1 span{font-family:var(--font-body);font-size:var(--text-base);font-weight:600;color:var(--color-muted);letter-spacing:.02em;margin-left:var(--space-2xs)}
.report-meta{display:flex;flex-wrap:wrap;gap:var(--space-2xs) var(--space-sm);padding:var(--space-sm) 0 var(--space-lg);border-top:var(--rule-hair) solid var(--color-rule);color:var(--color-muted);font-size:var(--text-xs)}.report-meta span:not(:last-child)::after,.report-meta time::after{content:'·';margin-left:var(--space-sm);color:var(--color-rule-strong)}.report-meta .stale{color:var(--color-warning);font-weight:700}.stale-note{margin:0 0 var(--space-lg);padding:var(--space-sm);background:var(--color-warning-paper);border-top:var(--rule-hair) solid var(--color-warning);border-bottom:var(--rule-hair) solid var(--color-warning);color:var(--color-warning);font-size:var(--text-sm);line-height:1.55}
.notes-reader{width:min(100%,720px)}.notes-report-head{display:block;padding-bottom:var(--space-lg);border-bottom:var(--rule-strong) solid var(--color-accent)}.notes-report-head h1{max-width:18ch}.notes-reader>.report-meta{border-top:0;padding-top:var(--space-sm)}
.lede{max-width:62ch;margin:0 0 var(--space-md);font-size:clamp(1.1875rem,1.7vw,1.375rem);font-weight:500;line-height:1.5;letter-spacing:-.005em}.setup{max-width:68ch;margin:0 0 var(--space-xl);font-size:var(--text-md);line-height:1.7;color:var(--color-muted)}
.report-section,.business,.chart-block{margin:var(--space-xl) 0}.report-section>h2,.business>h2,.chart-title,.preview-index>p{margin:0 0 var(--space-sm);padding-top:var(--space-sm);border-top:var(--rule-strong) solid var(--color-ink);font-size:var(--text-xs);font-weight:700;letter-spacing:.14em;text-transform:uppercase}.data-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:0 var(--space-xl);border-bottom:var(--rule-strong) solid var(--color-ink)}.data-row{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:var(--space-sm);padding:var(--space-xs) 0;border-bottom:var(--rule-hair) solid var(--color-rule);font-size:var(--text-base);line-height:1.45}.data-row span{color:var(--color-muted)}.data-row b{font-weight:500;text-align:right;overflow-wrap:anywhere;min-width:0}
.chart-frame{border:var(--rule-hair) solid var(--color-rule);background:var(--color-paper-raised);padding:var(--space-sm)}.chart-tabs,.ema-row{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-2xs)}.chart-tabs{margin-bottom:var(--space-xs)}.chart-tabs span,.ema-row span{font-size:var(--text-xs);color:var(--color-muted)}.chart-tabs .active{font-weight:700;color:var(--color-ink)}.axis{font-family:var(--font-sans);font-size:10px;fill:var(--color-faint)}.watermark{font-family:var(--font-sans);font-size:116px;font-weight:300;fill:var(--color-ink);opacity:.04}.ema-row{margin-top:var(--space-2xs)}.ema-row b{font-size:10px;letter-spacing:.12em;text-transform:uppercase}.ema-row i{width:12px;height:2px;display:inline-block;margin-right:var(--space-3xs)}.chart-source{margin:var(--space-2xs) 0 0;color:var(--color-faint);font-size:10px;font-style:italic}.business p{max-width:70ch;margin:0 0 var(--space-md);font-family:var(--font-display);font-size:var(--text-md);line-height:1.75}
.preview-index{margin:var(--space-2xl) 0 0}.preview-index ol{list-style:none;margin:0;padding:0;border-bottom:var(--rule-hair) solid var(--color-rule)}.preview-index li{display:grid;grid-template-columns:40px minmax(0,1fr);gap:var(--space-xs);padding:var(--space-xs) 0;border-top:var(--rule-hair) solid var(--color-rule);font-family:var(--font-display);font-size:var(--text-md);color:var(--color-muted)}.preview-index li span{font-family:var(--font-body);font-size:var(--text-xs);color:var(--color-faint)}
.paywall{margin:0 0 var(--space-3xl);padding:var(--space-xl) clamp(var(--space-md),6vw,var(--space-2xl));background:var(--color-ink-strong);color:var(--color-accent-ink);text-align:left}.paywall__kicker{margin:0 0 var(--space-xs);font-size:var(--text-xs);font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--color-accent)}.paywall h2{max-width:24ch;margin:0 0 var(--space-xs);font-family:var(--font-display);font-size:clamp(1.75rem,4vw,2.7rem);font-weight:430;line-height:1.05}.paywall>p:not(.paywall__kicker){max-width:54ch;margin:0 0 var(--space-md);color:var(--color-paper-deep);line-height:1.6}.paywall .primary{background:var(--color-paper);border-color:var(--color-paper);color:var(--color-ink-strong)}.paywall .primary:hover{background:var(--color-paper-deep);border-color:var(--color-paper-deep)}.signin{display:inline-block;margin-left:var(--space-sm);color:var(--color-paper);font-size:var(--text-sm);font-weight:600;text-underline-offset:4px;white-space:nowrap}
.related{margin-top:var(--space-2xl)}.section-head{display:flex;justify-content:space-between;align-items:baseline;gap:var(--space-md);padding-bottom:var(--space-sm);border-bottom:var(--rule-strong) solid var(--color-ink)}.section-head h2{margin:0;font-family:var(--font-display);font-size:var(--text-xl);font-weight:430}.section-head a{font-size:var(--text-sm);font-weight:600;white-space:nowrap;text-underline-offset:4px}.report-row{display:grid;grid-template-columns:56px minmax(0,1fr) auto;gap:var(--space-sm);align-items:center;padding:var(--space-sm) 0;border-bottom:var(--rule-hair) solid var(--color-rule);text-decoration:none}.report-row:hover .report-row__name{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:4px}.report-row:active{background:var(--color-paper-deep)}.report-row[aria-disabled=true]{opacity:.55;cursor:not-allowed;pointer-events:none}.report-row__copy{min-width:0}.report-row__name{display:block;font-family:var(--font-display);font-size:var(--text-md)}.report-row__name b{margin-left:var(--space-2xs);font-family:var(--font-body);font-size:var(--text-xs);letter-spacing:.04em}.report-row__teaser{display:-webkit-box;max-width:68ch;margin-top:var(--space-3xs);overflow:hidden;-webkit-line-clamp:2;-webkit-box-orient:vertical;color:var(--color-muted);font-size:var(--text-sm);line-height:1.45}.report-row__meta{display:flex;flex-direction:column;align-items:flex-end;gap:var(--space-3xs);color:var(--color-muted);font-size:var(--text-xs);white-space:nowrap}
.footer{padding:var(--space-2xl) clamp(var(--space-sm),5vw,var(--space-2xl));background:var(--color-paper-deep);border-top:var(--rule-hair) solid var(--color-rule)}.footer>*{max-width:920px;margin-left:auto;margin-right:auto}.footer__brand{display:block;font-size:var(--text-xl)}.footer>p:not(.disclosure){margin-top:var(--space-xs);margin-bottom:var(--space-lg);font-family:var(--font-display);font-size:var(--text-lg);line-height:1.25}.disclosure{font-size:var(--text-xs);line-height:1.6;color:var(--color-muted)}
.library-shell{width:min(100%,1040px);margin:0 auto;padding:var(--space-2xl) clamp(var(--space-sm),5vw,var(--space-xl)) var(--space-3xl)}.library-head{padding-bottom:var(--space-xl);border-bottom:var(--rule-strong) solid var(--color-ink)}.library-head h1{max-width:18ch;margin:0;font-size:var(--text-2xl)}.library-head>p:last-child{margin:var(--space-sm) 0 0;color:var(--color-muted)}.library-list{display:flex;flex-direction:column}.library-list .report-row{grid-template-columns:56px minmax(0,1fr) 160px}
/* .report-row sets display:grid, which outranks the user agent's [hidden]
   rule. Without this the filter counts correctly and hides nothing. */
.report-row[hidden]{display:none}
/* The finder's rule is the page's one strong horizontal, so the head above it
   gives its own up rather than stacking two 2px ink rules 60px apart. */
.library-head--open{border-bottom:0;padding-bottom:var(--space-lg)}
/* The finder. The library index is the public door now, so the search field is
   the focal artifact of the page: an editorial rule under a large field, not a
   rounded chrome search pill. Filtering is a hidden-attribute toggle over rows
   already in the DOM, so nothing here animates layout. */
.library-finder{padding:var(--space-lg) 0 var(--space-sm)}
.finder-field{display:flex;align-items:center;gap:var(--space-sm);padding:0 var(--space-2xs) var(--space-xs);border-bottom:var(--rule-strong) solid var(--color-ink);transition:border-color var(--dur-base) var(--ease-out)}
.finder-field:focus-within{border-color:var(--color-accent)}
.finder-icon{flex:0 0 20px;color:var(--color-faint);transition:color var(--dur-base) var(--ease-out)}
.finder-field:focus-within .finder-icon{color:var(--color-accent)}
#lib-q{flex:1;min-width:0;min-height:44px;border:0;background:none;color:var(--color-ink);font-family:var(--font-display);font-size:var(--text-lg);font-weight:400;letter-spacing:-.02em}
#lib-q::placeholder{color:var(--color-faint)}
#lib-q:focus{outline:none}
#lib-q::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
.finder-sectors{display:flex;flex-wrap:wrap;gap:var(--space-xs) var(--space-md);margin-top:var(--space-sm)}
.sector-chip{min-height:32px;padding:var(--space-3xs) 0;border:0;border-bottom:var(--rule-strong) solid transparent;background:none;color:var(--color-muted);font-family:var(--font-body);font-size:var(--text-sm);font-weight:500;cursor:pointer;transition:color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}
.sector-chip:hover{color:var(--color-ink)}
.sector-chip[aria-pressed=true]{color:var(--color-ink);border-bottom-color:var(--color-accent);font-weight:700}
.sector-chip:focus-visible,.finder-clear:focus-visible{outline:3px solid var(--color-focus);outline-offset:3px}
.finder-count{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-md);margin:var(--space-md) 0 0;color:var(--color-muted);font-size:var(--text-sm)}
.finder-clear{min-height:32px;padding:0;border:0;background:none;color:var(--color-ink);font-family:var(--font-body);font-size:var(--text-sm);font-weight:700;cursor:pointer;text-decoration:underline;text-underline-offset:4px}
/* The honest miss. An uncovered name is a demand signal, so it gets a real
   block and a real destination, not a greyed-out "no results". */
.library-miss{margin-top:var(--space-xl);padding:var(--space-xl) clamp(var(--space-sm),4vw,var(--space-xl));background:var(--color-paper-deep);border-top:var(--rule-strong) solid var(--color-ink)}
.library-miss h2{margin:0;max-width:22ch;font-family:var(--font-display);font-size:var(--text-xl);font-weight:430;letter-spacing:-.03em;line-height:1.1;overflow-wrap:anywhere}
.library-miss p{max-width:60ch;margin:var(--space-sm) 0 var(--space-lg);color:var(--color-muted);font-size:var(--text-sm);line-height:1.6}
@media(max-width:48rem){.report-shell{padding-top:var(--space-lg)}.data-grid{grid-template-columns:minmax(0,1fr)}.report-row,.library-list .report-row{grid-template-columns:48px minmax(0,1fr)}.report-row .company-mark{width:48px;height:48px;flex-basis:48px}.report-row .company-mark img{width:36px;height:36px}.report-row__meta{grid-column:2;flex-direction:row;align-items:center}.section-head{align-items:flex-start}.paywall{margin-left:calc(var(--space-sm) * -1);margin-right:calc(var(--space-sm) * -1)}.footer>p:not(.disclosure){font-size:var(--text-md)}}
@media(max-width:30rem){.topbar{min-height:64px;padding:var(--space-xs) var(--space-sm)}.brand{font-size:1.25rem}.topbar__cta{padding-left:var(--space-sm);padding-right:var(--space-sm)}.report-head{align-items:flex-start}.report-head h1{font-size:2rem}.report-head h1 span{display:block;margin:var(--space-3xs) 0 0}.report-meta{display:grid;grid-template-columns:minmax(0,1fr)}.report-meta span:not(:last-child)::after,.report-meta time::after{content:'';margin:0}.paywall{padding:var(--space-lg) var(--space-sm)}.paywall .primary{width:100%}.signin{display:block;margin:var(--space-sm) 0 0}.section-head{display:block}.section-head a{display:inline-block;margin-top:var(--space-2xs)}.report-row__teaser{-webkit-line-clamp:3}.report-row__meta{flex-wrap:wrap}.library-shell{padding-top:var(--space-xl)}#lib-q{font-size:var(--text-md)}.library-head--open{padding-bottom:var(--space-sm)}.library-finder{padding-top:var(--space-md)}
/* The sector row scrolls sideways on a phone. The fade says so, instead of
   letting a chip look accidentally guillotined at the bezel. */
.finder-sectors{gap:var(--space-2xs) var(--space-sm);margin-top:var(--space-xs);overflow-x:auto;flex-wrap:nowrap;scrollbar-width:none;-webkit-overflow-scrolling:touch;-webkit-mask-image:linear-gradient(to right,#000 86%,transparent);mask-image:linear-gradient(to right,#000 86%,transparent)}
.finder-sectors::-webkit-scrollbar{display:none}.sector-chip{white-space:nowrap}.finder-count{flex-wrap:wrap;gap:var(--space-2xs)}.library-miss .primary{width:100%}
/* Kind and date collapse onto one line on a phone. Without a separator they
   read as one run-on string ("Moat Dive Aug 28, 2026"). */
.library-list .report-row__meta>span::after{content:'·';margin-left:var(--space-2xs);color:var(--color-faint)}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}

.topbar nav{display:flex;align-items:center;gap:24px}.topbar nav a:not(.topbar__cta){color:inherit;text-decoration:none}.topbar nav a:focus-visible{outline:2px solid currentColor;outline-offset:4px}@media(max-width:680px){.topbar{flex-wrap:wrap;gap:18px}.topbar nav{width:100%;gap:18px;flex-wrap:wrap;font-size:14px}}
/* Phones: brand + Subscribe share the first row, the four links take the
   second, matching the home, database and portfolio pages. The button sits
   inside the nav in this markup, so it is lifted out by position. */
@media(max-width:680px){.topbar{position:relative}.topbar nav{gap:18px}.topbar nav .topbar__cta{position:absolute;top:12px;right:16px;min-height:40px;padding:8px 16px;font-size:13px}}
.topbar nav a[aria-current="page"]{font-weight:700}

.is-paid .paywall{display:none}

/* One reading size for the report body; matches the BON business column. */
.report-section p,.report-section li{max-width:68ch;font-size:var(--text-md);line-height:1.72}.report-section p{margin:0 0 var(--space-md)}
.methodology p,.methodology li{max-width:none;margin:0 0 var(--space-2xs);font-size:var(--text-xs);line-height:1.55;color:var(--color-muted)}
.data-row--text{grid-template-columns:minmax(0,1fr);gap:var(--space-3xs)}.data-row--text b{text-align:left;font-weight:500}
