Spaces:
Running
Running
| @import "tailwindcss"; | |
| /* --------------------------------------------------------------------------- | |
| LedgerLens — "Instrument of record" | |
| Second identity. The first ("Obsidian & Acid") was a near-black ground with a | |
| single acid-lime accent, chosen to avoid colliding with a sibling project — a | |
| good reason that happened to land on the most-generated look there is. Neon on | |
| black is the house style of every AI-built dashboard, so adding more glow to it | |
| would have made this page *more* templated, not more futuristic. | |
| The futurism here is borrowed from the subject instead. This product's promise | |
| is a record that cannot be forged or rewritten, and that world already has a | |
| visual language: security printing, assay marks, engraved instruments, | |
| oxidised metal. Verdigris and copper are the colours of metal that has proven | |
| it is old; bone is the colour of the paper such things are printed on. | |
| Three axes, each derived from the product rather than from a mood: | |
| hue metallurgical — verdigris, copper, bone on slate-teal black | |
| geometry engraved rules and machined chamfers; no blur, no rounding | |
| argument verification is quiet, exception is loud (see --color-pass) | |
| The inversion is the point. Most dashboards shout green for success, which | |
| trains the eye to skip the only state that needs a person. Here DONE is nearly | |
| silent and NEEDS REVIEW carries the sodium flare. | |
| --------------------------------------------------------------------------- */ | |
| @theme { | |
| --color-base: #050b0a; | |
| --color-base-raised: #0a1614; | |
| --color-base-sunken: #020605; | |
| --color-panel: #0a1513; | |
| --color-panel-top: #0f1f1c; | |
| /* Verdigris: oxidised copper, the colour of security ink and proven age. | |
| Desaturated and blue-shifted on purpose — it must never read as neon. */ | |
| --color-accent: #4fd1a5; | |
| --color-accent-dim: #2a6b56; | |
| --color-accent-glow: rgb(79 209 165 / 0.34); | |
| /* Copper does the structural work: engraved rules, seals, chamfer ticks. */ | |
| --color-copper: #b87333; | |
| --color-copper-dim: rgb(184 115 51 / 0.32); | |
| --color-ink: #e6e2d3; | |
| --color-ink-muted: #9aa39c; | |
| --color-ink-faint: #5d6a64; | |
| /* State only — never decoration. `pass` is deliberately the quietest colour on | |
| the page: a verified document is the uninteresting outcome and must not | |
| compete with the one asking for a human. */ | |
| --color-pass: #6f9c88; | |
| --color-flag: #e2564d; | |
| --color-warn: #e8a33d; | |
| --color-hairline: rgb(154 163 156 / 0.16); | |
| --color-hairline-strong: rgb(184 115 51 / 0.34); | |
| --font-engraved: var(--font-instrument-serif), ui-serif, Georgia, serif; | |
| --font-sans: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif; | |
| --font-mono: var(--font-geist-mono), ui-monospace, "SF Mono", monospace; | |
| } | |
| :root { | |
| color-scheme: dark; | |
| /* The machined corner cut, shared by every panel so the silhouette is | |
| consistent: top-right and bottom-left are chamfered, the other two are | |
| square. Asymmetry reads as engineered rather than merely rounded-off. */ | |
| --bevel: polygon( | |
| 0 0, | |
| calc(100% - 15px) 0, | |
| 100% 15px, | |
| 100% 100%, | |
| 15px 100%, | |
| 0 calc(100% - 15px) | |
| ); | |
| --bevel-sm: polygon( | |
| 0 0, | |
| calc(100% - 8px) 0, | |
| 100% 8px, | |
| 100% 100%, | |
| 8px 100%, | |
| 0 calc(100% - 8px) | |
| ); | |
| } | |
| html, | |
| body { | |
| background-color: var(--color-base); | |
| color: var(--color-ink); | |
| } | |
| body { | |
| font-family: var(--font-sans); | |
| -webkit-font-smoothing: antialiased; | |
| text-rendering: optimizeLegibility; | |
| min-height: 100dvh; | |
| } | |
| /* -------------------------------------------------------------------------- | |
| Backdrop: a technical grid, one violet wash, and a fine scanline field. | |
| No blur anywhere in this design. | |
| -------------------------------------------------------------------------- */ | |
| .backdrop-grid { | |
| position: fixed; | |
| inset: 0; | |
| z-index: -2; | |
| pointer-events: none; | |
| background-color: var(--color-base); | |
| background-image: | |
| radial-gradient(1100px 560px at 50% -12%, rgb(79 209 165 / 0.055), transparent 62%), | |
| radial-gradient(760px 460px at 88% 4%, rgb(184 115 51 / 0.11), transparent 60%), | |
| linear-gradient(to right, rgb(79 209 165 / 0.035) 1px, transparent 1px), | |
| linear-gradient(to bottom, rgb(79 209 165 / 0.035) 1px, transparent 1px); | |
| background-size: | |
| 100% 100%, | |
| 100% 100%, | |
| 64px 64px, | |
| 64px 64px; | |
| mask-image: radial-gradient(ellipse 110% 74% at 50% 0%, #000 52%, transparent 100%); | |
| } | |
| /* Engine-turning. The interference of two fine arcs is what guilloché is — the | |
| pattern on a banknote or a share certificate, difficult to reproduce and | |
| therefore used to prove a document is the original. Kept at a very low | |
| amplitude: it should read as the texture of the surface, not as an effect. */ | |
| .scanlines { | |
| position: fixed; | |
| inset: 0; | |
| z-index: 1; | |
| pointer-events: none; | |
| background-image: | |
| repeating-radial-gradient( | |
| circle at 18% -10%, | |
| rgb(184 115 51 / 0.028) 0 1px, | |
| transparent 1px 9px | |
| ), | |
| repeating-radial-gradient( | |
| circle at 84% 118%, | |
| rgb(79 209 165 / 0.022) 0 1px, | |
| transparent 1px 11px | |
| ); | |
| } | |
| /* An engraved rule: a bright hairline sitting on its own shadow, the way an | |
| intaglio line sits proud of the paper. */ | |
| .engraved { | |
| border-top: 1px solid rgb(184 115 51 / 0.22); | |
| box-shadow: 0 -1px 0 rgb(0 0 0 / 0.55); | |
| } | |
| /* -------------------------------------------------------------------------- | |
| Panels: hard-edged, chamfered, solid. `clip-path` removes the border on the | |
| cut edges, so contrast does the work a border would — the panel fill is | |
| deliberately lighter than the base rather than translucent. | |
| -------------------------------------------------------------------------- */ | |
| .panel { | |
| position: relative; | |
| background: linear-gradient(180deg, var(--color-panel-top) 0%, var(--color-panel) 100%); | |
| clip-path: var(--bevel); | |
| } | |
| .panel-hover { | |
| transition: | |
| background 200ms ease, | |
| transform 200ms ease; | |
| } | |
| .panel-hover:hover { | |
| background: linear-gradient(180deg, #142b26 0%, #0d1c19 100%); | |
| } | |
| /* An acid hairline along the top edge, and a machined tick in the chamfer. */ | |
| .edge-light::before { | |
| content: ""; | |
| position: absolute; | |
| inset-inline: 0; | |
| top: 0; | |
| height: 1px; | |
| background: linear-gradient( | |
| 90deg, | |
| transparent, | |
| var(--color-accent-glow) 30%, | |
| var(--color-accent-glow) 70%, | |
| transparent | |
| ); | |
| } | |
| .edge-light::after { | |
| content: ""; | |
| position: absolute; | |
| top: 0; | |
| right: 0; | |
| width: 15px; | |
| height: 15px; | |
| background: linear-gradient(45deg, transparent 49%, var(--color-copper) 49% 52%, transparent 52%); | |
| opacity: 0.65; | |
| } | |
| /* Corner brackets — the HUD tell. */ | |
| .ticks::before, | |
| .ticks::after { | |
| content: ""; | |
| position: absolute; | |
| width: 9px; | |
| height: 9px; | |
| border-color: var(--color-copper); | |
| opacity: 0.55; | |
| } | |
| .ticks::before { | |
| left: 7px; | |
| top: 7px; | |
| border-left: 1px solid; | |
| border-top: 1px solid; | |
| } | |
| .ticks::after { | |
| right: 7px; | |
| bottom: 7px; | |
| border-right: 1px solid; | |
| border-bottom: 1px solid; | |
| } | |
| .bevel { | |
| clip-path: var(--bevel); | |
| } | |
| .bevel-sm { | |
| clip-path: var(--bevel-sm); | |
| } | |
| /* -------------------------------------------------------------------------- | |
| Glows — flat rings, no soft blur halo. | |
| -------------------------------------------------------------------------- */ | |
| .glow-accent { | |
| box-shadow: | |
| inset 0 0 0 1px rgb(79 209 165 / 0.45), | |
| 0 0 22px -8px rgb(79 209 165 / 0.7); | |
| } | |
| .glow-pass { | |
| box-shadow: | |
| inset 0 0 0 1px rgb(111 156 136 / 0.4), | |
| 0 0 20px -10px rgb(111 156 136 / 0.6); | |
| } | |
| .glow-flag { | |
| box-shadow: | |
| inset 0 0 0 1px rgb(226 86 77 / 0.45), | |
| 0 0 24px -8px rgb(226 86 77 / 0.65); | |
| } | |
| .glow-warn { | |
| box-shadow: | |
| inset 0 0 0 1px rgb(232 163 61 / 0.4), | |
| 0 0 20px -10px rgb(232 163 61 / 0.6); | |
| } | |
| /* -------------------------------------------------------------------------- | |
| Typography | |
| -------------------------------------------------------------------------- */ | |
| .tabular { | |
| font-variant-numeric: tabular-nums; | |
| font-feature-settings: "tnum"; | |
| } | |
| /* The engraved face, declared here rather than left to the generated utility. | |
| Everything in this file is unlayered, and unlayered declarations beat anything | |
| in `@layer utilities` — so a rule here is the one that actually lands. Used on | |
| the hero and panel titles only: the page is mono-dominant, and the serif is | |
| the human voice among the machine output. */ | |
| .font-engraved { | |
| font-family: var(--font-instrument-serif), ui-serif, Georgia, serif; | |
| font-weight: 400; | |
| } | |
| /* Mono-forward: this is a ledger, so labels read as machine output. */ | |
| .eyebrow { | |
| font-family: var(--font-mono); | |
| font-size: 0.625rem; | |
| letter-spacing: 0.2em; | |
| text-transform: uppercase; | |
| color: var(--color-ink-faint); | |
| font-weight: 500; | |
| } | |
| .stat { | |
| font-family: var(--font-mono); | |
| font-variant-numeric: tabular-nums; | |
| letter-spacing: -0.02em; | |
| } | |
| /* -------------------------------------------------------------------------- | |
| Segmented meter — the ▓▓▓░░ bar. A discrete readout suits a ledger better | |
| than a continuous progress bar. | |
| -------------------------------------------------------------------------- */ | |
| .meter { | |
| display: flex; | |
| gap: 2px; | |
| height: 4px; | |
| } | |
| .meter-cell { | |
| flex: 1; | |
| background: rgb(154 163 156 / 0.16); | |
| } | |
| .meter-cell[data-on="true"] { | |
| background: var(--color-accent); | |
| } | |
| .meter-cell[data-tone="pass"][data-on="true"] { | |
| background: var(--color-pass); | |
| } | |
| .meter-cell[data-tone="flag"][data-on="true"] { | |
| background: var(--color-flag); | |
| } | |
| .meter-cell[data-tone="warn"][data-on="true"] { | |
| background: var(--color-warn); | |
| } | |
| /* -------------------------------------------------------------------------- | |
| Pipeline motion | |
| -------------------------------------------------------------------------- */ | |
| @keyframes chevron-run { | |
| from { | |
| background-position: 0 0; | |
| } | |
| to { | |
| background-position: 16px 0; | |
| } | |
| } | |
| /* Marching chevrons instead of a sweeping gradient. */ | |
| .connector-active { | |
| background-image: repeating-linear-gradient( | |
| 90deg, | |
| var(--color-accent) 0px, | |
| var(--color-accent) 5px, | |
| transparent 5px, | |
| transparent 16px | |
| ); | |
| animation: chevron-run 0.55s linear infinite; | |
| } | |
| @keyframes breathe { | |
| 0%, | |
| 100% { | |
| opacity: 0.5; | |
| } | |
| 50% { | |
| opacity: 1; | |
| } | |
| } | |
| .breathe { | |
| animation: breathe 1.4s steps(8, end) infinite; | |
| } | |
| ::selection { | |
| background: rgb(79 209 165 / 0.3); | |
| color: #050b0a; | |
| } | |
| ::-webkit-scrollbar { | |
| width: 10px; | |
| height: 10px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: transparent; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: rgb(154 163 156 / 0.22); | |
| border: 3px solid transparent; | |
| background-clip: content-box; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: rgb(79 209 165 / 0.4); | |
| background-clip: content-box; | |
| } | |
| @media (prefers-reduced-motion: reduce) { | |
| *, | |
| *::before, | |
| *::after { | |
| animation-duration: 0.001ms ; | |
| animation-iteration-count: 1 ; | |
| transition-duration: 0.001ms ; | |
| } | |
| } | |