The database is the source of truth; the site is a view over it.
- packages/core/db/schema.sql: vendors, products, categories, the 8-dimension
instrument, assessments, scores, evidence, findings, off-ramp, plus the
derived v_product_score view the game reads.
- packages/core/db/build.mjs: rebuilds bigtech.db, absorbs the legacy 43-product
roster as unassessed, applies seeds, then verifies the instrument's own rules
(weights sum to 100, totals recompute, grades match bands, every score has a
rationale, no tier-4 evidence on a scored dimension, reproducible-build caps
actually enforced).
- packages/core/db/seed/0001-signal.sql: Signal Desktop 8.36.0-alpha.1 on linux,
75.9/100 grade B, weakest dimension local_data_exposure. Evidence points at
the re-runnable audit artifacts in the Servetus vault.
- packages/core/src/data/generated/catalog.{ts,json}: generated export.
Verified: 44 products, 1 assessed, all checks pass.
52 lines
No EOL
1.6 KiB
TypeScript
52 lines
No EOL
1.6 KiB
TypeScript
import { ArtSlotView } from '../components/ArtSlotView';
|
|
import type { LoginMethod } from '@bigtech-sucks/core';
|
|
|
|
interface Props {
|
|
onContinue: () => void;
|
|
onLogin: (method: LoginMethod) => void;
|
|
}
|
|
|
|
const loginOptions: { method: LoginMethod; label: string }[] = [
|
|
{ method: 'passkey', label: 'Passkey' },
|
|
{ method: 'email', label: 'Email' },
|
|
{ method: 'proton', label: 'Proton' },
|
|
{ method: 'google', label: 'Google' },
|
|
{ method: 'github', label: 'GitHub' },
|
|
{ method: 'anonymous', label: 'Ride in quiet' },
|
|
];
|
|
|
|
export function WelcomeScreen({ onContinue, onLogin }: Props) {
|
|
return (
|
|
<section className="screen welcome-screen">
|
|
<ArtSlotView slotId="title_illustration" />
|
|
<h1>Draw the Line</h1>
|
|
<p className="tagline">Your data doesn't have a party. Neither do we.</p>
|
|
<p className="lede">
|
|
A weary traveler's assessment — scope your exposure before you plan the crossing.
|
|
</p>
|
|
|
|
<div className="login-picker">
|
|
<p className="section-label">How are you riding in?</p>
|
|
<div className="login-grid">
|
|
{loginOptions.map(({ method, label }) => (
|
|
<button
|
|
key={method}
|
|
type="button"
|
|
className="btn btn-secondary"
|
|
onClick={() => {
|
|
onLogin(method);
|
|
onContinue();
|
|
}}
|
|
>
|
|
{label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<button type="button" className="btn btn-primary" onClick={onContinue}>
|
|
Meet the wagon boss
|
|
</button>
|
|
</section>
|
|
);
|
|
} |