/* ===================================================================== btc-intel — the component layer. Structure over decoration: hairlines, square corners, one accent, and mono for anything measured. Every value comes from tokens.css; nothing below invents a colour or a duration. ===================================================================== */ *, *::before, *::after { box-sizing: border-box; } html { -webkit-text-size-adjust: 100%; } body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--font-sans); font-size: var(--fs-body); line-height: var(--lh-body); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } h1, h2, h3 { margin: 0; font-weight: var(--weight-regular); line-height: var(--lh-head); text-wrap: balance; } h1 { font-size: var(--fs-h1); letter-spacing: var(--ls-h1); } h2 { font-size: var(--fs-h2); font-weight: var(--weight-medium); } h3 { font-size: var(--fs-h3); font-weight: var(--weight-semi); } p { margin: 0; } a { color: var(--evidence); text-decoration-color: color-mix(in srgb, var(--evidence) 35%, transparent); text-underline-offset: 2px; transition: color var(--dur-2) var(--ease-out); } a:hover { color: var(--evidence-hi); } button { font: inherit; color: inherit; } :focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); } ::selection { background: var(--evidence); color: var(--on-evidence); } /* -- primitives ------------------------------------------------------- */ .label { font-family: var(--font-mono); font-size: var(--fs-label); font-weight: var(--weight-medium); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--ink-muted); } .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; } .num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-data); } .soft { color: var(--ink-soft); } .muted { color: var(--ink-muted); } .measure { max-width: var(--measure); } .panel { background: var(--surface); border: var(--bw-hair) solid var(--rule); } .well { background: var(--sunk); border: var(--bw-hair) solid var(--rule); } .rule-t { border-top: var(--bw-hair) solid var(--rule); } .stack { display: flex; flex-direction: column; } /* Corner ticks instead of a full border: eight gradients on one element. */ .bracket { --bk: var(--rule); background-image: linear-gradient(var(--bk), var(--bk)), linear-gradient(var(--bk), var(--bk)), linear-gradient(var(--bk), var(--bk)), linear-gradient(var(--bk), var(--bk)), linear-gradient(var(--bk), var(--bk)), linear-gradient(var(--bk), var(--bk)), linear-gradient(var(--bk), var(--bk)), linear-gradient(var(--bk), var(--bk)); background-repeat: no-repeat; background-size: 7px 1px, 1px 7px, 7px 1px, 1px 7px, 7px 1px, 1px 7px, 7px 1px, 1px 7px; background-position: 0 0, 0 0, 100% 0, 100% 0, 0 100%, 0 100%, 100% 100%, 100% 100%; } /* -- buttons ---------------------------------------------------------- */ .btn { display: inline-flex; align-items: center; gap: var(--sp-2); padding: 0.5rem 0.875rem; border: 0; border-radius: var(--r-1); background: transparent; font-family: var(--font-mono); font-size: var(--fs-label); font-weight: var(--weight-medium); letter-spacing: var(--ls-label); text-transform: uppercase; white-space: nowrap; cursor: pointer; transition: background-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out), opacity var(--dur-2) var(--ease-out); } .btn:disabled { opacity: 0.45; cursor: not-allowed; } .btn-primary { background: var(--evidence); color: var(--on-evidence); } .btn-primary:hover:not(:disabled) { background: var(--evidence-hi); } .btn-primary:active:not(:disabled) { background: var(--evidence-lo); } .btn-ghost { --bk: var(--ink-faint); color: var(--ink); } .btn-ghost:hover:not(:disabled) { --bk: var(--evidence); color: var(--evidence); } .btn-quiet { color: var(--ink-muted); padding-inline: var(--sp-2); } .btn-quiet:hover:not(:disabled) { color: var(--ink); } .btn[aria-pressed="true"] { background: var(--evidence-w12); color: var(--evidence); } /* -- chips ------------------------------------------------------------ */ .chip { display: inline-flex; align-items: center; gap: var(--sp-1); padding: 0.0625rem 0.375rem; background: var(--sunk); border: var(--bw-hair) solid transparent; border-radius: var(--r-0); font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: 0.04em; color: var(--ink-soft); white-space: nowrap; } .chip-caution { background: var(--caution-bg); color: var(--caution); border-color: color-mix(in srgb, var(--caution) 40%, transparent); } .chip-confirmed { background: var(--confirmed-bg); color: var(--confirmed); } .id-chip { font-family: var(--font-mono); font-size: var(--fs-small); background: var(--sunk); padding: 0.0625rem 0.3125rem; color: var(--ink-soft); white-space: nowrap; } /* -- shell ------------------------------------------------------------ */ .shell { display: grid; grid-template-columns: var(--rail-w) minmax(0, 1fr); gap: var(--rail-gap); max-width: var(--content-max); margin-inline: auto; padding: var(--sp-6) var(--sp-5) var(--sp-9); } .rail { position: sticky; top: var(--sp-6); align-self: start; height: max-content; } .wordmark { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: 1.0625rem; letter-spacing: -0.02em; color: var(--ink); text-decoration: none; } .wordmark-mark { width: 0.875rem; height: 0.875rem; background: var(--evidence); clip-path: polygon(0 0, 45% 0, 45% 45%, 100% 45%, 100% 100%, 55% 100%, 55% 55%, 0 55%); } .rail-nav { display: flex; flex-direction: column; gap: 0.125rem; margin-top: var(--sp-6); } .rail-link { display: flex; align-items: center; gap: var(--sp-2); padding: 0.25rem 0; color: var(--ink-muted); text-decoration: none; transition: color var(--dur-2) var(--ease-out); } .rail-link:hover { color: var(--ink); } .rail-link[aria-current="page"] { color: var(--ink); } .rail-link::before { content: ""; width: 6px; height: 6px; background: transparent; } .rail-link[aria-current="page"]::before { background: var(--evidence); } .rail-divider { margin: var(--sp-5) 0 var(--sp-4); border: 0; border-top: 1px dashed var(--rule); } .subnav { display: flex; flex-direction: column; gap: 0.125rem; margin-top: var(--sp-3); } .subnav a { display: grid; grid-template-columns: 1.25rem 1fr; align-items: center; gap: var(--sp-2); padding: 0.1875rem 0; color: var(--ink-muted); font-size: var(--fs-small); text-decoration: none; } .subnav a::before { content: ""; height: 1px; width: 0.5rem; background: var(--ink-faint); transition: width var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-out); } .subnav a[aria-current="true"] { color: var(--ink); } .subnav a[aria-current="true"]::before { width: 1.25rem; background: var(--evidence); } /* Half-filled square: the theme control, drawn rather than typed, because a glyph for this is not in every font. */ .theme-swatch { width: 9px; height: 9px; border: 1px solid currentColor; background: linear-gradient(90deg, currentColor 50%, transparent 50%); } .rail-foot { margin-top: var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-2); align-items: flex-start; } .content { min-width: 0; } .section { margin-top: var(--sp-8); } .section:first-child { margin-top: 0; } .section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); padding-bottom: var(--sp-2); border-bottom: var(--bw-hair) solid var(--rule); margin-bottom: var(--sp-4); } /* -- stat blocks ------------------------------------------------------ */ .stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); border-top: var(--bw-hair) solid var(--rule); border-left: var(--bw-hair) solid var(--rule); } .stat { padding: var(--sp-4); border-right: var(--bw-hair) solid var(--rule); border-bottom: var(--bw-hair) solid var(--rule); background: var(--surface); } .stat-value { display: flex; align-items: baseline; gap: 0.125rem; margin-top: var(--sp-3); font-family: var(--font-mono); font-size: var(--fs-stat); font-weight: var(--weight-regular); letter-spacing: var(--ls-stat); line-height: 1; font-variant-numeric: tabular-nums; } .stat-unit { font-size: var(--fs-small); letter-spacing: 0; color: var(--ink-muted); } /* -- tables ----------------------------------------------------------- */ .table-wrap { overflow-x: auto; border: var(--bw-hair) solid var(--rule); background: var(--surface); } table.data { width: 100%; border-collapse: collapse; } table.data th { position: sticky; top: 0; z-index: 1; background: var(--surface); border-bottom: var(--bw-hair) solid var(--rule); padding: var(--sp-2) var(--sp-3); font-family: var(--font-mono); font-size: var(--fs-label); font-weight: var(--weight-medium); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--ink-muted); text-align: left; white-space: nowrap; } table.data th button { display: inline-flex; align-items: center; gap: var(--sp-1); background: none; border: 0; padding: 0; font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; cursor: pointer; } table.data th button:hover { color: var(--ink); } table.data td { padding: var(--sp-2) var(--sp-3); white-space: nowrap; border-bottom: var(--bw-hair) solid var(--rule-soft); height: var(--row-h); vertical-align: middle; } table.data tbody tr { transition: background-color var(--dur-2) var(--ease-out); } table.data tbody tr:hover { background: var(--evidence-w7); } table.data tbody tr:focus-within { background: var(--evidence-w7); } table.data tbody tr[data-settled="true"] { opacity: 0.55; } .num-cell { text-align: right; font-family: var(--font-mono); font-size: var(--fs-data); font-variant-numeric: tabular-nums; } .gutter-code { font-family: var(--font-mono); font-size: var(--fs-label); color: var(--ink-faint); letter-spacing: 0.06em; } .row-link { color: var(--ink); text-decoration: none; font-family: var(--font-mono); font-size: var(--fs-data); white-space: nowrap; } .row-link:hover { color: var(--evidence); } .reason-cell { color: var(--ink-soft); font-size: var(--fs-small); max-width: 30ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* -- risk meter ------------------------------------------------------- */ .risk { display: inline-flex; align-items: center; gap: var(--sp-2); white-space: nowrap; } .risk-cells { font-family: var(--font-mono); letter-spacing: -0.04em; color: var(--risk-ink); } .risk-score { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-data); } .risk-label { font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--risk-ink); } .risk-chip { display: inline-flex; align-items: center; gap: var(--sp-1); padding: 0.0625rem 0.375rem; background: var(--risk-bg); color: var(--risk-ink); font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: var(--ls-label); text-transform: uppercase; } /* -- filters ---------------------------------------------------------- */ .filters { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); padding: var(--sp-3) 0; } .field { display: inline-flex; align-items: center; gap: var(--sp-2); } .field select, .field input[type="search"] { font-family: var(--font-mono); font-size: var(--fs-data); color: var(--ink); background: var(--surface); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1); padding: 0.25rem 0.375rem; } .field input[type="range"] { accent-color: var(--evidence); width: 8rem; } /* -- notice ----------------------------------------------------------- */ .notice { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); background: var(--caution-bg); border: var(--bw-hair) solid color-mix(in srgb, var(--caution) 35%, transparent); color: var(--ink); } .notice .label { color: var(--caution); } /* A build mismatch is not a passing status: it stays until it is fixed. */ .build-notice { margin-bottom: var(--sp-5); border-color: color-mix(in srgb, var(--risk-high) 45%, transparent); background: var(--risk-high-bg); } .build-notice .label { color: var(--risk-high); } /* -- the field: dark in both themes ----------------------------------- */ .field-panel { position: relative; background: var(--field); color: var(--field-ink); border: var(--bw-hair) solid var(--field-rule); overflow: hidden; } .field-panel .label { color: var(--field-muted); } .field-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3); border-bottom: var(--bw-hair) solid var(--field-rule); } .field-legend { display: flex; flex-wrap: wrap; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3); border-top: var(--bw-hair) solid var(--field-rule); font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: 0.06em; color: var(--field-muted); } .legend-swatch { display: inline-block; width: 8px; height: 8px; margin-right: var(--sp-1); vertical-align: middle; } .field-btn { background: transparent; color: var(--field-ink); --bk: #2a3a72; } .field-btn:hover:not(:disabled) { --bk: var(--field-muted); background: #ffffff0f; } /* -- home header ------------------------------------------------------ */ .header-field { position: relative; min-height: 13rem; display: flex; align-items: flex-end; padding: var(--sp-5); } .header-field canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; } .header-copy { position: relative; max-width: 34rem; } .header-copy h1 { font-size: var(--fs-display); letter-spacing: var(--ls-display); line-height: var(--lh-display); color: var(--field-ink); } /* -- charts ----------------------------------------------------------- */ .bar-row { display: grid; grid-template-columns: minmax(7rem, 12rem) 1fr 3rem; align-items: center; gap: var(--sp-3); padding: 0.25rem 0; font-size: var(--fs-small); } .bar-track { height: 0.5rem; background: var(--sunk); } .bar-fill { height: 100%; background: var(--evidence); transform-origin: left center; } .case-row { display: grid; grid-template-columns: 13rem auto minmax(0, 1fr); align-items: center; gap: var(--sp-4); padding: var(--sp-3) 0; border-bottom: var(--bw-hair) solid var(--rule-soft); font-size: var(--fs-small); color: var(--ink); text-decoration: none; } .case-row:hover { background: var(--evidence-w7); color: var(--ink); } .case-reason { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } @media (max-width: 48rem) { .case-row { grid-template-columns: minmax(0, 1fr); gap: var(--sp-1); } .case-reason { white-space: normal; } } /* -- entity ----------------------------------------------------------- */ .entity-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--sp-5); } .gauge { display: flex; align-items: center; gap: var(--sp-3); } .gauge svg { display: block; } .gauge-arc { transition: none; } .evidence-list { display: flex; flex-direction: column; } .evidence-item { display: grid; grid-template-columns: 5.5rem 1fr auto; align-items: center; gap: var(--sp-3); padding: var(--sp-2) 0; border-bottom: var(--bw-hair) solid var(--rule-soft); font-family: var(--font-mono); font-size: var(--fs-small); } .evidence-item a, .evidence-item span.value { overflow-wrap: anywhere; } /* Leads live on their own surface, deliberately. Attribution is a different kind of claim from suspicion and must not read as part of the reasons. */ .leads { background: var(--sunk); border: var(--bw-hair) solid var(--rule); padding: var(--sp-4); } .lead { display: grid; grid-template-columns: 1fr auto; gap: var(--sp-2) var(--sp-4); padding: var(--sp-3) 0; border-bottom: var(--bw-hair) solid var(--rule); } .lead:last-child { border-bottom: 0; padding-bottom: 0; } .lead-ip { font-family: var(--font-mono); font-size: var(--fs-data); } .taint-path { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); font-family: var(--font-mono); font-size: var(--fs-small); } /* -- command palette -------------------------------------------------- */ dialog.palette { width: min(34rem, calc(100vw - 2rem)); margin-top: 12vh; padding: 0; border: 0; border-radius: var(--r-1); background: var(--surface); color: var(--ink); box-shadow: var(--shadow-float); } dialog.palette::backdrop { background: color-mix(in srgb, var(--ink) 35%, transparent); } .palette input { width: 100%; padding: var(--sp-4); border: 0; border-bottom: var(--bw-hair) solid var(--rule); background: transparent; color: inherit; font-family: var(--font-mono); font-size: var(--fs-body); } .palette input:focus { outline: none; } .palette ul { list-style: none; margin: 0; padding: var(--sp-2); max-height: 18rem; overflow-y: auto; } .palette li button { display: flex; width: 100%; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3); background: transparent; border: 0; border-radius: var(--r-1); font-family: var(--font-mono); font-size: var(--fs-small); text-align: left; cursor: pointer; } .palette li[data-active="true"] button, .palette li button:hover { background: var(--evidence-w12); color: var(--evidence); } .palette-foot { padding: var(--sp-2) var(--sp-4); border-top: var(--bw-hair) solid var(--rule); } /* -- toasts ----------------------------------------------------------- */ .toasts { position: fixed; right: var(--sp-4); bottom: var(--sp-4); z-index: 40; display: flex; flex-direction: column; gap: var(--sp-2); } .toast { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-4); background: var(--surface); border-radius: var(--r-1); box-shadow: var(--shadow-toast); font-size: var(--fs-small); } /* -- skeletons -------------------------------------------------------- */ .skeleton { background: linear-gradient( 90deg, var(--sunk) 0%, color-mix(in srgb, var(--sunk) 60%, var(--surface)) 50%, var(--sunk) 100% ); background-size: 200% 100%; animation: shimmer 1.4s linear infinite; height: 1rem; } @keyframes shimmer { to { background-position: -200% 0; } } /* -- ascii / braille decorations -------------------------------------- */ .ascii { font-family: var(--font-mono); font-size: 0.5rem; line-height: 0.72; letter-spacing: 0.04em; white-space: pre; user-select: none; pointer-events: none; color: var(--field-muted); } .fade-b { mask-image: linear-gradient(to bottom, #000 45%, transparent 100%); } /* -- view transitions -------------------------------------------------- */ @view-transition { navigation: auto; } ::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--dur-3); animation-timing-function: var(--ease-out); } /* -- responsive -------------------------------------------------------- */ @media (max-width: 62rem) { .shell { grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); padding: var(--sp-4) var(--sp-4) var(--sp-8); } .rail { position: static; } .rail-nav { flex-direction: row; flex-wrap: wrap; gap: var(--sp-4); margin-top: var(--sp-4); } .subnav { display: none; } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; } @view-transition { navigation: none; } } /* Visually hidden, still read aloud. */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }