/* Layout and component rules for scrapcode.network, in the "Machine Cant /
   Forge" system. Every colour, face, size and duration comes from tokens.css
   — see the rule at the top of that file for why there are no literals here.

   The two exceptions are marked `/* not a token */` where they occur, and both
   are ratios rather than values.

   Design rules being honoured that are easy to undo by accident:
     · corners are SQUARED — --radius-3 (4px) is as round as a control gets,
       and the only circles in the system are presence dots and swatches;
     · transitions are 120ms/--ease and touch COLOUR AND BORDER ONLY. Nothing
       here moves, scales or bounces;
     · Major Mono Display is the brand face and appears exactly once, in the
       wordmark. It is never body copy, and never a heading;
     · mono labels are tracked and uppercased;
     · ghost text is --ink-2 and is the only grey.                          */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	margin: 0;
	background: var(--bg);
	/* Paints the overscroll gutter and the area behind a rubber-band scroll in
	   the theme's own black instead of the browser's white. */
	color-scheme: dark;
}

[data-theme="light"] {
	color-scheme: light;
}

/* Body owns the viewport height and the row split, NOT .stage — which is where
   the `min-height: 100dvh` used to live, and it moved here when the footer
   arrived. With `1fr auto` the stage takes whatever is left over and the footer
   sits exactly on the fold; leave the 100dvh on .stage as well and the footer
   is pushed one footer-height BELOW it, so every page grows a pointless
   scrollbar. */
body {
	margin: 0;
	min-height: 100vh;
	/* `100dvh` rather than `100vh` because on mobile Safari and Chrome `vh` is
	   the LARGEST viewport — it excludes the browser chrome that is actually on
	   screen, so a `100vh` stage is taller than the visible area and a
	   perfectly centred mark sits measurably low. `dvh` tracks the live
	   viewport; the `100vh` line above is the fallback for anything older. */
	min-height: 100dvh;
	display: grid;
	grid-template-rows: 1fr auto;
	background: var(--bg);
	color: var(--ink-1);
	font-family: var(--font-body);
	/* Antialiasing hints, not aesthetics — they stop bone-on-void type from
	   rendering heavier than it was drawn, which this palette is prone to. */
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

/* The centring. The mark centres in the space ABOVE the footer rather than in
   the raw viewport, so it sits a half-footer high of dead centre — about 14px,
   and imperceptible. If it ever needs to be exact, take the footer out of the
   flow (`position: fixed`) rather than reaching for a negative margin. */
.stage {
	display: grid;
	place-items: center;
	padding: var(--space-8) var(--space-6);
}

/* ── the lockup ───────────────────────────────────────────────────────────
   The Machine Cant mark, as LIVE TYPE rather than an asset — which is what
   the design system ships (`components/brand/Logo.jsx`, and its readme: "No
   vector export yet — the wordmark is live type"). Two consequences worth
   knowing, because they are why the earlier note in here recommending inline
   SVG is now moot:

     · it themes itself. The word is --ink-0, the cursor and strapline are
       --accent, so the light theme needs no second asset and no `<img>` swap;
     · it is real text, so the page has a real <h1> and the brand name is
       selectable, searchable and readable by a screen reader.

   Everything is sized in `em` off --lockup-size, the way Logo.jsx derives
   every dimension from its `size` prop. Changing that one token rescales the
   whole mark with its proportions intact. */
.lockup {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	gap: var(--lockup-gap);
	font-size: var(--lockup-size);
	/* The em basis for every child. Nothing else about this element is type. */
	line-height: var(--leading-tight);
}

/* The ghost line: `01110011 01100011` is `s` `c` in binary. The system allows
   it on a splash or a login and nowhere else. aria-hidden in the markup — it
   is a texture, and read aloud it is sixteen digits of nothing. */
.lockup-ghost {
	margin: 0;
	font-family: var(--font-mono);
	font-size: var(--lockup-ghost);
	letter-spacing: var(--tracking-brand);
	color: var(--ink-2);
	/* The strapline below is tracked by the same amount, and tracking adds
	   space after the LAST glyph too — so both lines sit visibly left of
	   centre unless that trailing space is given back. */
	text-indent: var(--tracking-brand);
}

/* The wordmark. An <h1>: it is the page's heading as well as the logo, and
   there is no other candidate on a page with one element on it. */
.lockup-word {
	display: inline-flex;
	align-items: center;
	gap: 0.11em;
	margin: 0;
	font-family: var(--font-display);
	/* Inherits --lockup-size from .lockup. `font-size: 1em` rather than a
	   token, so the <h1>'s UA default (2em) does not multiply it. */
	font-size: 1em;
	font-weight: 400; /* Major Mono Display ships one weight */
	line-height: 1;
	white-space: nowrap;
	color: var(--ink-0);
	/* Major Mono Display is unicase: lowercase input renders as the caps-like
	   forms in the specimen. The markup says "scrapcode" in lowercase — which
	   is the brand's own casing in prose — and the face does the rest. Do NOT
	   add text-transform here; it would make the source disagree with the
	   brand for no visible change. */
}

/* The block cursor. Always --accent, per the brand rules. */
.lockup-cursor {
	width: var(--lockup-cursor-w);
	height: var(--lockup-cursor-h);
	background: var(--accent);
	/* Squared. The one shape in the mark, and the system's corners are hard. */
	border-radius: var(--radius-0);
	/* It does NOT blink. The system's motion rule is colour and border only,
	   and a terminal cursor blinking forever on an always-open tab is exactly
	   the kind of infinite animation that costs a compositor layer for nothing.
	   The block reads as a cursor standing still. */
}

.lockup-strap {
	margin: 0;
	font-family: var(--font-mono);
	font-size: var(--lockup-strap);
	letter-spacing: var(--tracking-brand);
	color: var(--accent);
	text-indent: var(--tracking-brand); /* see .lockup-ghost */
}

/* ── the site footer ──────────────────────────────────────────────────────
   Present on every page, and on the landing page it is the ONLY thing sharing
   the viewport with the mark. Kept to one line of small mono for exactly that
   reason: it has to be reachable — Google's consent screen requires a policy
   link a person can actually find — without competing with the logo. */
.site-foot {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-3) var(--space-6);
	align-items: center;
	justify-content: center;
	padding: var(--space-6);
	font-family: var(--font-mono);
	font-size: var(--text-xs);
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	color: var(--ink-2);
}

.site-foot a {
	color: inherit;
	text-decoration: none;
	transition: color var(--dur-fast) var(--ease);
}

.site-foot a:hover {
	color: var(--accent);
}

/* ── the theme toggle ─────────────────────────────────────────────────────
   A ghost button, to the spec in components/core/Button.jsx: no fill, 1px
   --border-2, --ink-1 text, and on hover --ink-0 text with a brass border.
   Mono rather than body copy because its label is a state word, not prose. */
.theme-toggle {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	min-height: var(--hit-min);
	padding: var(--space-1) var(--space-4);
	background: none;
	border: 1px solid var(--border-2);
	border-radius: var(--radius-3);
	color: var(--ink-1);
	font-family: var(--font-mono);
	font-size: var(--text-2xs);
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	cursor: pointer;
	transition:
		color var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease),
		background var(--dur-fast) var(--ease);
}

.theme-toggle:hover {
	color: var(--ink-0);
	border-color: var(--accent);
}

/* Hidden until theme.js runs. A toggle that cannot toggle is worse than no
   toggle, so with JS off or blocked the button never appears and the page
   stays in whatever theme it loaded. */
.theme-toggle[hidden] {
	display: none;
}

/* ── prose pages (privacy, terms) ─────────────────────────────────────────
   `.page` is the padding box; `.prose` is the measure. Two elements rather
   than one because the horizontal padding must apply at the viewport edge
   while the max-width applies to the text — collapse them and the padding
   eats into the measure instead of sitting outside it. */
.page {
	padding: var(--space-10) var(--space-6) var(--space-6);
}

.prose {
	max-width: var(--measure);
	margin: 0 auto;
	font-size: var(--fs-prose);
	line-height: var(--leading-relaxed);
	/* Body copy is --ink-1, so headings, links and <strong> can each step UP
	   to --ink-0 for emphasis without needing a colour of their own. That is
	   why almost nothing below names a colour. */
	color: var(--ink-1);
}

/* The back-link to the mark. A mono label, tracked and uppercased. */
.prose .eyebrow {
	margin: 0 0 var(--space-9);
	font-family: var(--font-mono);
	font-size: var(--text-xs);
	letter-spacing: var(--tracking-wide);
	text-transform: uppercase;
}

.prose .eyebrow a {
	color: var(--ink-2);
	text-decoration: none;
	transition: color var(--dur-fast) var(--ease);
}

.prose .eyebrow a:hover {
	color: var(--accent);
}

/* The document title. Share Tech Mono, NOT Major Mono Display — the brand
   face is the wordmark's alone, and "Privacy Policy" set in it would read as
   a second logo. */
.prose h1 {
	margin: 0 0 var(--space-2);
	font-family: var(--font-mono);
	font-size: var(--text-2xl);
	font-weight: 400;
	line-height: var(--leading-tight);
	letter-spacing: var(--tracking-wide);
	text-transform: uppercase;
	color: var(--ink-0);
}

/* The date line, and the system's mono aside convention: it reads
   "// last updated …" in the markup. */
.prose .meta {
	margin: 0 0 var(--space-10);
	font-family: var(--font-mono);
	font-size: var(--fs-prose-sm);
	letter-spacing: var(--tracking-label);
	color: var(--ink-2);
}

.prose h2 {
	/* Asymmetric margins: a heading belongs to the text BELOW it, so the space
	   above must be clearly larger or the page reads as evenly spaced blocks
	   with no hierarchy. */
	margin: var(--space-10) 0 var(--space-5);
	padding-top: var(--space-5);
	border-top: 1px solid var(--border);
	font-family: var(--font-mono);
	font-size: var(--text-md);
	font-weight: 400; /* Share Tech Mono ships one weight */
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	color: var(--accent);
}

.prose h3 {
	margin: var(--space-8) 0 var(--space-3);
	font-family: var(--font-mono);
	font-size: var(--fs-prose-sm);
	font-weight: 400;
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	color: var(--ink-0);
}

.prose p {
	margin: 0 0 var(--space-6);
}

.prose ul {
	margin: 0 0 var(--space-6);
	padding-left: var(--space-7);
	/* Squared bullets rather than discs — the system's only circles are
	   presence dots and swatches, and a row of round bullets down a legal page
	   is the most visible place to break that. */
	list-style: square;
}

.prose li {
	margin-bottom: var(--space-3);
}

.prose li::marker {
	color: var(--accent);
}

.prose strong {
	color: var(--ink-0);
	font-weight: 600;
}

.prose code {
	font-family: var(--font-mono);
	/* 0.95em is NOT a token: it is the mono/proportional x-height correction,
	   relative to whatever size it lands in, so it stays right when the design
	   system re-pitches the scale. A token here would be an absolute size, and
	   an absolute size would need maintaining per context. */
	font-size: 0.95em; /* not a token */
	color: var(--ink-0);
	background: var(--panel-2);
	padding: 0.1em 0.35em;
	border-radius: var(--radius-1);
}

.prose a {
	color: var(--accent);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.15em;
	transition: color var(--dur-fast) var(--ease);
}

.prose a:hover {
	color: var(--ink-0);
}

/* The foot of a policy page, pointing at its sibling. */
.prose-nav {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-6);
	margin-top: var(--space-10);
	padding-top: var(--space-6);
	border-top: 1px solid var(--border);
	font-family: var(--font-mono);
	font-size: var(--text-xs);
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
}

.prose-nav a {
	color: var(--ink-2);
	text-decoration: none;
	transition: color var(--dur-fast) var(--ease);
}

.prose-nav a:hover {
	color: var(--accent);
}

/* One focus ring for the whole site. The system specifies focus for INPUTS
   (swap the border to brass, no outer ring) and this page has none — a link
   has no border to swap, so it gets a brass outline instead. :focus-visible
   rather than :focus, so a mouse click does not leave a ring behind. */
a:focus-visible,
button:focus-visible {
	outline: 1px solid var(--accent);
	outline-offset: 3px;
	border-radius: var(--radius-1);
}
