btc-intel / web /src /styles /base.css
Anish-g's picture
Deploy btc-intel on free ZeroGPU Gradio Space (part 2)
e94832e verified
Raw History Blame Contribute Delete
21 kB
/* =====================================================================
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;
}