/* addabit — shared stylesheet for every tool page.
 *
 * One request, cached across the whole site, so a tool page after the first is
 * just its own markup. Everything below the token block is site chrome and the
 * small set of form primitives the tools compose from; a tool should almost
 * never need its own CSS.
 */

@font-face {
	font-family: 'Space Mono';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url('/fonts/space-mono-latin-400-normal.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
		U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
		U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Space Mono';
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url('/fonts/space-mono-latin-700-normal.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
		U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
		U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Fira Code Variable';
	font-style: normal;
	font-weight: 300 700;
	font-display: swap;
	src: url('/fonts/fira-code-latin-wght-normal.woff2') format('woff2-variations');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
		U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
		U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* adabit design tokens — drop-in, no build step.
 *
 * Dark is the source of truth. Light inverts the grays with the hue forced
 * back to purple (plain inversion lands on a warm yellow cast), then darkens
 * muted/subtle until they clear 4.5:1 on the cream base, and swaps each accent
 * for a deeper cousin. Both columns are the exact values, already computed —
 * do not re-derive or eyeball them.
 *
 * No [data-theme] attribute means "follow the system"; a theme toggle sets it.
 */

:root {
	color-scheme: light dark;
	color: var(--color-text);

	/* Corner radii. Base scale 4/6/8/12px multiplied by 1.4. */
	--radius-xs: 5.6px;
	--radius-sm: 8.4px;
	--radius-md: 11.2px;
	--radius-lg: 16.8px;

	/* Fonts. Space Mono is the UI/chrome face; Fira Code is reading text and
	   code. Kosugi Maru covers Japanese in both. */
	--font-ui: 'Space Mono', 'Kosugi Maru', monospace;
	--font-content: 'Fira Code Variable', 'Kosugi Maru', monospace;
}

/* ---- dark (default) ---- */
:root,
:root[data-theme='dark'] {
	--color-base: #0d181f;
	--color-surface: #1f1d2e;
	--color-overlay: #26233a;
	--color-muted: #8683a3;
	--color-subtle: #908caa;
	--color-text: #e0def4;

	--color-love: #eb6f92;
	--color-gold: #f6c177;
	--color-rose: #ebbcba;
	--color-pine: #3e8fb0;
	--color-foam: #9ccfd8;
	--color-iris: #c4a7e7;

	--color-site-name: #cc7e97;
	--color-time: #5bcefa;

	--hl-low: #21202e;
	--hl-med: #403d52;
	--hl-high: #524f67;
}

:root[data-theme='dark'] {
	color-scheme: dark;
}

/* ---- light ---- */
@media (prefers-color-scheme: light) {
	:root:not([data-theme='dark']) {
		--color-base: #ebe0f2;
		--color-surface: #dbd1e2;
		--color-overlay: #d2c5dc;
		--color-muted: #594a63;
		--color-subtle: #4d4056;
		--color-text: #180b21;

		--color-love: #94435c;
		--color-gold: #8a5a08;
		--color-rose: #9d4844;
		--color-pine: #286983;
		--color-foam: #356871;
		--color-iris: #6d548a;

		--color-site-name: #994866;
		--color-time: #0a6f97;

		--hl-low: #d9d1df;
		--hl-med: #b9adc2;
		--hl-high: #a698b0;
	}
}

:root[data-theme='light'] {
	color-scheme: light;

	--color-base: #ebe0f2;
	--color-surface: #dbd1e2;
	--color-overlay: #d2c5dc;
	--color-muted: #594a63;
	--color-subtle: #4d4056;
	--color-text: #180b21;

	--color-love: #94435c;
	--color-gold: #8a5a08;
	--color-rose: #9d4844;
	--color-pine: #286983;
	--color-foam: #356871;
	--color-iris: #6d548a;

	--color-site-name: #994866;
	--color-time: #0a6f97;

	--hl-low: #d9d1df;
	--hl-med: #b9adc2;
	--hl-high: #a698b0;
}

/* ---- baseline ---- */

html {
	background-color: var(--color-base);
	font-family: var(--font-ui);
	overflow-wrap: break-word;
	transition:
		color 0.25s,
		background-color 0.15s;
}

/* Smooth scrolling only when it's wanted — this applies to every in-page jump. */
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

body {
	margin: auto;
	max-width: 769px;
}

code,
kbd,
pre {
	font-family: var(--font-content);
	font-feature-settings: 'cv01', 'cv02', 'ss01', 'ss03', 'ss05', 'cv29', 'ss02', 'ss09';
	overflow-wrap: break-word;
}

/* Reading text is Fira Code; UI chrome stays Space Mono even inside it. */
.content {
	font-family: var(--font-content);
	margin: 0 1rem;
}

h1,
h2,
h3,
h4,
h5,
h6,
button,
#footer {
	font-family: var(--font-ui);
}

h1,
h2,
h3 {
	font-weight: 300;
	margin-bottom: 0.15rem;
}

a {
	color: var(--color-foam);
	text-decoration: dashed underline var(--color-muted);
	text-underline-offset: 3px;
	transition: color 0.25s;
}

a:hover,
a:focus {
	color: var(--color-iris);
	text-decoration-style: solid;
}

/* Off-site links get a marker so leaving the site reads as leaving the site. */
.external-link::after {
	content: '↗';
	margin-left: 0.15em;
	font-size: 0.75em;
	color: var(--color-muted);
	vertical-align: super;
}

hr {
	max-width: 100vw;
	border: none;
	border-top: 1px solid var(--color-subtle);
}

:focus-visible {
	outline: 2px solid var(--color-iris);
	outline-offset: 2px;
}

/* Squircle corners everywhere. Chromium-only today; other engines just get a
   plain rounded corner, which is a fine fallback. */
*,
*::before,
*::after {
	corner-shape: superellipse(2.2);
}

/* Opt-outs: things that are round rather than rounded (avatars, icon buttons,
   status pills). Add selectors here per project. */
.is-round {
	corner-shape: round;
}

/* ---- surfaces ---- */

/* Static glass panel for content cards. */
.panel {
	background: color-mix(in srgb, var(--color-surface) 55%, transparent);
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
	border: 1px solid var(--hl-med);
	border-radius: var(--radius-lg);
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

/* Glass pill link/button. Tints key off --color-text so the frost stays
   visible in light mode. */
.glass-nav-link {
	position: relative;
	overflow: hidden;
	padding: 0.6rem 1.2rem;
	border-radius: var(--radius-md);
	font-weight: 500;
	text-decoration: none;
	background: color-mix(in srgb, var(--color-text) 5%, transparent);
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
	border: 1px solid color-mix(in srgb, var(--color-text) 10%, transparent);
	/* Explicit list instead of `all`: these sit above backdrop-filter layers,
	   so keeping the transition surface small keeps hovers cheap. */
	transition:
		background 0.3s cubic-bezier(0.4, 0, 0.2, 1),
		border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
		box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1),
		color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
		transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Sheen that sweeps across on hover. */
.glass-nav-link::before {
	content: '';
	position: absolute;
	top: 0;
	left: -100%;
	width: 100%;
	height: 100%;
	background: linear-gradient(
		90deg,
		transparent,
		color-mix(in srgb, var(--color-text) 20%, transparent),
		transparent
	);
	transition: left 0.5s ease;
}

.glass-nav-link:hover {
	background: color-mix(in srgb, var(--color-text) 12%, transparent);
	transform: translateY(-2px);
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.glass-nav-link:hover::before {
	left: 100%;
}

/* Heavier glass, for cards that get the 3D hover tilt. */
.glass-element {
	position: relative;
	background: color-mix(in srgb, var(--color-text) 8%, transparent);
	backdrop-filter: blur(12px);
	-webkit-backdrop-filter: blur(12px);
	border: 1px solid color-mix(in srgb, var(--color-text) 15%, transparent);
	border-radius: var(--radius-lg);
	box-shadow:
		0 8px 32px rgba(0, 0, 0, 0.1),
		inset 0 1px 0 color-mix(in srgb, var(--color-text) 20%, transparent);
	transform-style: preserve-3d;
	will-change: transform;
}

/* Top-edge highlight. */
.glass-element::before {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 1px;
	background: linear-gradient(
		90deg,
		transparent,
		color-mix(in srgb, var(--color-text) 40%, transparent),
		transparent
	);
	pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
	.glass-nav-link,
	.glass-nav-link::before {
		transition: none;
	}
	.glass-nav-link:hover {
		transform: none;
	}
}

/* ---- lists ---- */

/* Arrow bullets instead of discs. */
.list-default ul {
	list-style: '-> ';
}

.list-default ol,
.list-default ul {
	padding-left: 1rem;
	margin-left: 0.5rem;
	margin-right: 1rem;
}

.list-none ul,
.list-none ol {
	list-style: none;
	padding-left: 0.5rem;
	margin-left: 0.25rem;
}

/* ---- color utilities ---- */

.text-default {
	color: var(--color-text);
}
.text-muted {
	color: var(--color-muted);
}
.text-subtle {
	color: var(--color-subtle);
}
.text-love {
	color: var(--color-love);
}
.text-gold {
	color: var(--color-gold);
}
.text-rose {
	color: var(--color-rose);
}
.text-pine {
	color: var(--color-pine);
}
.text-foam {
	color: var(--color-foam);
}
.text-iris {
	color: var(--color-iris);
}

/* ==========================================================================
   Site chrome
   ========================================================================== */

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

body {
	max-width: none;
	margin: 0;
	background: var(--color-base);
	color: var(--color-text);
	font-family: var(--font-ui);
	min-height: 100vh;
	-webkit-text-size-adjust: 100%;
}

.skip {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 100;
	padding: 0.6rem 1rem;
	background: var(--color-overlay);
	border: 1px solid var(--color-iris);
	border-radius: var(--radius-md);
}
.skip:focus { left: 0.5rem; top: 0.5rem; }

.shell { display: grid; grid-template-columns: 244px minmax(0, 1fr); min-height: 100vh; }

/* --- rail --- */

.rail {
	position: sticky;
	top: 0;
	align-self: start;
	height: 100vh;
	display: flex;
	flex-direction: column;
	gap: 1.15rem;
	padding: 1.4rem 1.1rem 1.1rem;
	border-right: 1px solid var(--hl-low);
	background: color-mix(in srgb, var(--color-surface) 40%, transparent);
	overflow-y: auto;
	scrollbar-width: thin;
	scrollbar-color: var(--hl-med) transparent;
}

.mark { display: flex; align-items: center; gap: 0.6rem; text-decoration: none; color: inherit; flex: none; }
.mark:hover { color: inherit; }
.mark-grid { display: grid; grid-template-columns: repeat(3, 5px); grid-auto-rows: 5px; gap: 2px; flex: none; }
.mark-grid i { background: var(--hl-high); border-radius: 1px; }
.mark-grid i.on { background: var(--color-foam); }
.mark-text { font-size: 1rem; letter-spacing: -0.02em; }
.mark-text b { font-weight: 700; }
.mark-text span { color: var(--color-foam); }

.rail-search { flex: none; }
.rail-search input {
	width: 100%;
	background: color-mix(in srgb, var(--color-text) 5%, transparent);
	border: 1px solid var(--hl-med);
	border-radius: var(--radius-md);
	color: var(--color-text);
	font-family: var(--font-content);
	font-size: 0.8rem;
	padding: 0.45rem 0.7rem;
	outline: none;
	transition: border-color 0.2s;
}
.rail-search input:focus { border-color: var(--color-foam); }
.rail-search input::placeholder { color: var(--color-muted); }

.rail nav { display: flex; flex-direction: column; gap: 1rem; flex: 1; }
.rail-group { display: flex; flex-direction: column; gap: 0.1rem; }
.rail-label {
	font-size: 0.62rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--color-muted);
	padding: 0 0.55rem;
	margin-bottom: 0.35rem;
}
.rail nav a {
	padding: 0.34rem 0.55rem;
	border-radius: var(--radius-sm);
	font-size: 0.81rem;
	color: var(--color-subtle);
	text-decoration: none;
	border: 1px solid transparent;
	transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.rail nav a:hover { background: color-mix(in srgb, var(--color-text) 6%, transparent); color: var(--color-text); }
.rail nav a[aria-current='page'] {
	background: color-mix(in srgb, var(--color-foam) 14%, transparent);
	border-color: color-mix(in srgb, var(--color-foam) 32%, transparent);
	color: var(--color-text);
}
.rail-group.hidden, .rail nav a.hidden { display: none; }

.rail-foot { flex: none; display: flex; align-items: center; gap: 0.5rem; padding-top: 0.9rem; border-top: 1px solid var(--hl-low); }
.kbd-hint { font-size: 0.68rem; color: var(--color-muted); display: flex; align-items: center; gap: 0.3rem; }
kbd {
	background: var(--hl-low);
	border: 1px solid var(--hl-med);
	border-radius: var(--radius-xs);
	padding: 0.08rem 0.32rem;
	font-size: 0.68rem;
	font-family: var(--font-ui);
	color: var(--color-subtle);
}
.theme-btn {
	margin-left: auto;
	background: none;
	border: 1px solid var(--hl-med);
	border-radius: var(--radius-md);
	color: var(--color-muted);
	padding: 0.3rem 0.55rem;
	font-size: 0.7rem;
	cursor: pointer;
	font-family: var(--font-ui);
	transition: color 0.2s, border-color 0.2s;
}
.theme-btn:hover { color: var(--color-foam); border-color: var(--color-foam); }

/* --- main --- */

main { padding: 2.4rem 2.4rem 5rem; max-width: 1000px; width: 100%; }

.eyebrow {
	font-size: 0.66rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--color-foam);
	margin: 0 0 0.8rem;
}
h1 {
	font-size: clamp(1.8rem, 4vw, 2.6rem);
	font-weight: 300;
	letter-spacing: -0.035em;
	line-height: 1.08;
	text-wrap: balance;
	margin: 0 0 0.6rem;
}
h1 b { font-weight: 700; color: var(--color-foam); }
.lede {
	font-family: var(--font-content);
	font-size: 0.97rem;
	line-height: 1.65;
	color: var(--color-subtle);
	max-width: 62ch;
	margin: 0 0 2rem;
}
.back { display: inline-block; font-size: 0.74rem; color: var(--color-muted); text-decoration: none; margin-bottom: 1.1rem; }
.back:hover { color: var(--color-foam); }

/* ==========================================================================
   Form primitives — the vocabulary every tool is built from
   ========================================================================== */

.tool { display: flex; flex-direction: column; gap: 1.1rem; }
.row { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; }
.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1rem; }
.grid3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0.8rem; }
.spacer { flex: 1; }

.field { display: flex; flex-direction: column; gap: 0.4rem; min-width: 0; }
.field > label, .flabel {
	font-size: 0.63rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--color-muted);
	display: flex;
	align-items: baseline;
	gap: 0.5rem;
}
.field > label .hint, .flabel .hint { letter-spacing: 0; text-transform: none; font-size: 0.7rem; color: var(--color-muted); margin-left: auto; }

input[type='text'], input[type='number'], input[type='search'], input[type='date'],
input[type='datetime-local'], input[type='time'], textarea, select {
	width: 100%;
	background: color-mix(in srgb, var(--color-surface) 50%, transparent);
	border: 1px solid var(--hl-med);
	border-radius: var(--radius-md);
	color: var(--color-text);
	font-family: var(--font-content);
	font-size: 0.9rem;
	padding: 0.6rem 0.8rem;
	outline: none;
	transition: border-color 0.2s, box-shadow 0.2s;
}
textarea { resize: vertical; min-height: 8.5rem; line-height: 1.6; }
input:focus, textarea:focus, select:focus {
	border-color: var(--color-foam);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-foam) 16%, transparent);
}
input::placeholder, textarea::placeholder { color: var(--color-muted); }
select { cursor: pointer; appearance: none; padding-right: 2rem;
	background-image: linear-gradient(45deg, transparent 50%, var(--color-muted) 50%), linear-gradient(135deg, var(--color-muted) 50%, transparent 50%);
	background-position: right 1rem center, right 0.72rem center;
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
}
input[type='range'] { accent-color: var(--color-foam); padding: 0; background: none; border: none; }
input[type='color'] { padding: 0.2rem; height: 2.6rem; cursor: pointer; }
.field.bad input, .field.bad textarea { border-color: var(--color-love); }
.field.bad input:focus, .field.bad textarea:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-love) 18%, transparent); }

.mono-out {
	max-width: 100%;
	font-family: var(--font-content);
	font-size: 0.88rem;
	line-height: 1.6;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	background: color-mix(in srgb, var(--color-text) 4%, transparent);
	border: 1px solid var(--hl-med);
	border-radius: var(--radius-md);
	padding: 0.7rem 0.85rem;
	min-height: 2.8rem;
	margin: 0;
	overflow-x: auto;
}
.mono-out:empty::before { content: attr(data-empty); color: var(--color-muted); }
.mono-out.scroll { max-height: 22rem; overflow-y: auto; white-space: pre; }

button.btn, a.btn {
	background: color-mix(in srgb, var(--color-text) 5%, transparent);
	border: 1px solid var(--hl-med);
	border-radius: var(--radius-md);
	color: var(--color-subtle);
	font-family: var(--font-ui);
	font-size: 0.78rem;
	padding: 0.45rem 0.85rem;
	cursor: pointer;
	text-decoration: none;
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	transition: color 0.2s, border-color 0.2s, background 0.2s;
}
button.btn:hover, a.btn:hover { color: var(--color-text); border-color: var(--hl-high); }
button.btn.primary { color: var(--color-foam); border-color: color-mix(in srgb, var(--color-foam) 45%, transparent); }
button.btn.primary:hover { background: color-mix(in srgb, var(--color-foam) 14%, transparent); }
button.btn:disabled { opacity: 0.45; cursor: default; }
button.btn.ok { color: var(--color-pine); border-color: var(--color-pine); }

.seg { display: inline-flex; border: 1px solid var(--hl-med); border-radius: var(--radius-md); overflow: hidden; }
.seg button {
	background: none;
	border: none;
	border-right: 1px solid var(--hl-med);
	color: var(--color-muted);
	font-family: var(--font-ui);
	font-size: 0.75rem;
	padding: 0.42rem 0.8rem;
	cursor: pointer;
	transition: color 0.2s, background 0.2s;
}
.seg button:last-child { border-right: none; }
.seg button:hover { color: var(--color-text); }
.seg button[aria-pressed='true'] { background: color-mix(in srgb, var(--color-foam) 16%, transparent); color: var(--color-foam); }

.check { display: inline-flex; align-items: center; gap: 0.42rem; font-size: 0.78rem; color: var(--color-subtle); cursor: pointer; }
.check input { accent-color: var(--color-foam); width: 0.95rem; height: 0.95rem; cursor: pointer; }

.note {
	font-family: var(--font-content);
	font-size: 0.8rem;
	line-height: 1.7;
	color: var(--color-subtle);
	border-left: 2px solid var(--color-foam);
	background: color-mix(in srgb, var(--color-text) 4%, transparent);
	border-radius: 0 var(--radius-md) var(--radius-md) 0;
	padding: 0.7rem 0.95rem;
	margin: 0;
}
.note.warn { border-left-color: var(--color-gold); }
.note.bad { border-left-color: var(--color-love); }
.note b { color: var(--color-text); font-weight: 400; }

.stats { display: flex; flex-wrap: wrap; gap: 1.6rem; font-variant-numeric: tabular-nums; }
.stats div { display: flex; flex-direction: column; gap: 0.1rem; }
.stats span { font-size: 1.15rem; font-weight: 300; letter-spacing: -0.02em; color: var(--color-foam); }
.stats em { font-style: normal; font-size: 0.62rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--color-muted); }

.panelbox {
	border: 1px solid var(--hl-med);
	border-radius: var(--radius-lg);
	background: color-mix(in srgb, var(--color-surface) 45%, transparent);
	padding: 1.1rem;
}

.tablewrap { overflow-x: auto; max-width: 100%; border: 1px solid var(--hl-low); border-radius: var(--radius-lg); }
table { border-collapse: collapse; width: 100%; font-size: 0.82rem; }
th, td { text-align: left; padding: 0.55rem 0.85rem; border-bottom: 1px solid var(--hl-low); }
th { font-size: 0.62rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--color-muted); font-weight: 400; background: color-mix(in srgb, var(--color-text) 4%, transparent); }
td { font-family: var(--font-content); color: var(--color-subtle); }
td.k { color: var(--color-foam); white-space: nowrap; }
td.num { font-variant-numeric: tabular-nums; text-align: right; }
tbody tr:last-child td { border-bottom: none; }

.drop {
	border: 1px dashed var(--hl-high);
	border-radius: var(--radius-lg);
	padding: 1.4rem;
	text-align: center;
	font-size: 0.8rem;
	color: var(--color-muted);
	font-family: var(--font-content);
	cursor: pointer;
	transition: border-color 0.2s, background 0.2s, color 0.2s;
}
.drop:hover, .drop.over { border-color: var(--color-foam); color: var(--color-text); background: color-mix(in srgb, var(--color-foam) 8%, transparent); }

.swatch { width: 100%; height: 4.5rem; border-radius: var(--radius-md); border: 1px solid var(--hl-med); }

/* ==========================================================================
   Home
   ========================================================================== */

.searchbig {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	padding: 0.8rem 1.05rem;
	border: 1px solid var(--hl-med);
	border-radius: var(--radius-lg);
	background: color-mix(in srgb, var(--color-surface) 50%, transparent);
	margin-bottom: 1.1rem;
}
.searchbig:focus-within { border-color: var(--color-foam); box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-foam) 16%, transparent); }
.searchbig input { border: none; background: none; padding: 0; box-shadow: none !important; font-size: 0.95rem; }
.searchbig .caret { color: var(--color-foam); font-weight: 700; }

.filters { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 1.8rem; }
.chip {
	background: none;
	border: 1px solid var(--hl-med);
	border-radius: var(--radius-sm);
	color: var(--color-muted);
	font-family: var(--font-ui);
	font-size: 0.71rem;
	padding: 0.26rem 0.62rem;
	cursor: pointer;
	transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.chip:hover { color: var(--color-text); }
.chip[aria-pressed='true'] { color: var(--color-base); background: var(--color-foam); border-color: var(--color-foam); }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 0.8rem; }
.bit {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding: 1rem;
	border-radius: var(--radius-lg);
	background: color-mix(in srgb, var(--color-text) 4%, transparent);
	border: 1px solid var(--hl-low);
	text-decoration: none;
	color: inherit;
	position: relative;
	overflow: hidden;
	transition: border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), background 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.bit::after { content: ''; position: absolute; inset: 0 auto 0 0; width: 2px; background: var(--accent, var(--color-foam)); opacity: 0; transition: opacity 0.3s; }
.bit:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--accent, var(--color-foam)) 45%, transparent); background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.bit:hover::after { opacity: 1; }
.bit.hidden { display: none; }
.bit h3 { margin: 0; font-size: 0.92rem; font-weight: 700; letter-spacing: -0.01em; color: var(--color-text); }
.bit p { margin: 0; font-family: var(--font-content); font-size: 0.79rem; line-height: 1.55; color: var(--color-muted); flex: 1; }
.bit-top { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.tag {
	font-size: 0.6rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--accent, var(--color-foam));
	border: 1px solid color-mix(in srgb, var(--accent, var(--color-foam)) 35%, transparent);
	border-radius: var(--radius-xs);
	padding: 0.13rem 0.38rem;
	flex: none;
}
/* The page opens on the headline and the search; the explanation sits at the
   bottom for anyone who wants it, rather than in front of the tools. */
.home-title { margin-bottom: 1.5rem; }

.homefoot {
	margin-top: 3.5rem;
	padding-top: 1.6rem;
	border-top: 1px solid var(--hl-low);
	font-family: var(--font-content);
	max-width: 62ch;
}
.homefoot .eyebrow { margin-bottom: 0.7rem; }
.homefoot p { font-size: 0.86rem; line-height: 1.7; color: var(--color-muted); margin: 0 0 0.8rem; }
.homefoot p:last-child { margin-bottom: 0; }
.homefoot .byline { margin-top: 1.2rem; font-size: 0.8rem; }

.empty { grid-column: 1 / -1; padding: 2.5rem 1rem; text-align: center; color: var(--color-muted); font-family: var(--font-content); font-size: 0.88rem; }

/* --- prose --- */

.prose { max-width: 64ch; font-family: var(--font-content); }
.prose h2 { font-family: var(--font-ui); font-size: 1.1rem; font-weight: 700; letter-spacing: -0.02em; margin: 2.4rem 0 0.7rem; color: var(--color-text); }
.prose p { line-height: 1.75; color: var(--color-subtle); margin: 0 0 1rem; font-size: 0.9rem; }
.prose ul { list-style: '-> '; padding-left: 1.1rem; color: var(--color-subtle); font-size: 0.9rem; line-height: 1.85; }
.prose code { background: var(--hl-low); border: 1px solid var(--hl-med); border-radius: var(--radius-xs); padding: 0.08rem 0.33rem; font-size: 0.86em; color: var(--color-foam); }

/* ==========================================================================
   Command palette
   ========================================================================== */

.palette-bg {
	position: fixed;
	inset: 0;
	background: color-mix(in srgb, var(--color-base) 74%, transparent);
	display: none;
	align-items: flex-start;
	justify-content: center;
	padding-top: 13vh;
	z-index: 50;
}
.palette-bg.open { display: flex; }
.palette {
	width: min(560px, 92vw);
	background: var(--color-overlay);
	border: 1px solid var(--hl-high);
	border-radius: var(--radius-lg);
	box-shadow: 0 24px 64px rgba(0, 0, 0, 0.35);
	overflow: hidden;
}
.palette input { border: none; border-bottom: 1px solid var(--hl-med); border-radius: 0; background: none; box-shadow: none !important; padding: 0.9rem 1.1rem; font-size: 0.95rem; }
.palette ul { list-style: none; margin: 0; padding: 0.35rem; max-height: 46vh; overflow-y: auto; }
.palette li { padding: 0.55rem 0.75rem; border-radius: var(--radius-md); font-size: 0.84rem; color: var(--color-subtle); display: flex; justify-content: space-between; gap: 1rem; cursor: pointer; }
.palette li[aria-selected='true'] { background: color-mix(in srgb, var(--color-foam) 16%, transparent); color: var(--color-text); }
.palette li small { color: var(--color-muted); font-size: 0.67rem; }

/* ==========================================================================
   Mobile top bar and drawer

   Below the breakpoint the rail becomes an off-canvas drawer: the same markup,
   the same links, moved off screen and brought back over a scrim. Nothing is
   duplicated, so there is only one nav to keep correct.
   ========================================================================== */

.topbar { display: none; }

.iconbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	flex: none;
	padding: 0;
	background: none;
	border: 1px solid transparent;
	border-radius: var(--radius-md);
	color: var(--color-subtle);
	cursor: pointer;
	transition: color 0.2s, background 0.2s, border-color 0.2s;
}
.iconbtn:hover { color: var(--color-text); background: color-mix(in srgb, var(--color-text) 7%, transparent); }

.scrim {
	position: fixed;
	inset: 0;
	z-index: 39;
	background: color-mix(in srgb, var(--color-base) 65%, transparent);
	backdrop-filter: blur(2px);
	-webkit-backdrop-filter: blur(2px);
	opacity: 0;
	transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.scrim.show { opacity: 1; }

@media (max-width: 860px) {
	.topbar {
		position: sticky;
		top: 0;
		z-index: 30;
		display: flex;
		align-items: center;
		gap: 0.5rem;
		padding: 0.4rem 0.6rem;
		padding-top: max(0.4rem, env(safe-area-inset-top));
		border-bottom: 1px solid var(--hl-low);
		background: color-mix(in srgb, var(--color-base) 88%, transparent);
		backdrop-filter: blur(12px);
		-webkit-backdrop-filter: blur(12px);
	}
	.topbar .mark { flex: 1; min-width: 0; }
	.topbar .mark-text { font-size: 0.95rem; }

	/* minmax(0, 1fr), not 1fr: a bare 1fr is minmax(auto, 1fr), so the column
	   grows to fit its widest child and the whole page scrolls sideways instead
	   of the table or bit-row scrolling inside its own container. */
	.shell { grid-template-columns: minmax(0, 1fr); }
	main { min-width: 0; }

	.rail {
		position: fixed;
		top: 0;
		left: 0;
		bottom: 0;
		z-index: 40;
		width: min(19rem, 84vw);
		height: 100dvh;
		border-right: 1px solid var(--hl-med);
		background: var(--color-surface);
		box-shadow: 0 0 40px rgba(0, 0, 0, 0.4);
		transform: translateX(-102%);
		transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
		padding-top: max(1.4rem, env(safe-area-inset-top));
		padding-bottom: max(1.1rem, env(safe-area-inset-bottom));
		gap: 1rem;
	}
	.rail.open { transform: translateX(0); }

	/* The drawer carries its own identity; the top bar already shows the mark. */
	.rail > .mark { display: none; }
	.rail nav { flex-direction: column; gap: 1rem; }

	/* Comfortable thumb targets — 0.34rem rows are fine with a mouse and not
	   with a finger. */
	.rail nav a { padding: 0.62rem 0.7rem; font-size: 0.9rem; }
	.rail-search input { font-size: 16px; padding: 0.6rem 0.75rem; }

	main {
		padding: 1.4rem 1.05rem 4rem;
		padding-left: max(1.05rem, env(safe-area-inset-left));
		padding-right: max(1.05rem, env(safe-area-inset-right));
		padding-bottom: max(4rem, calc(2rem + env(safe-area-inset-bottom)));
	}

	h1 { font-size: 1.75rem; }
	.lede { font-size: 0.95rem; }

	/* 16px minimum stops iOS Safari zooming when a field takes focus. */
	input[type='text'], input[type='number'], input[type='search'], input[type='date'],
	input[type='datetime-local'], input[type='time'], textarea, select {
		font-size: 16px;
	}

	button.btn, a.btn { padding: 0.6rem 0.95rem; font-size: 0.82rem; min-height: 42px; }
	.seg { width: 100%; }
	.seg button { flex: 1; padding: 0.6rem 0.5rem; min-height: 42px; }
	.check { min-height: 34px; }
	.check input { width: 1.15rem; height: 1.15rem; }
	input[type='range'] { height: 34px; }

	.grid { grid-template-columns: 1fr; }
	.grid2, .grid3 { grid-template-columns: 1fr; }
	.searchbig { padding: 0.7rem 0.9rem; }
	.searchbig input { font-size: 16px; }

	.stats { gap: 1rem 1.4rem; }
	.stats span { font-size: 1.05rem; }

	/* Tables are the one thing that cannot reflow, so let them scroll. */
	table { min-width: 26rem; }
	th, td { padding: 0.5rem 0.65rem; }

	.calc { font-size: 0.85rem; }
	.calc input { width: 5rem; }
	.calc .eq { width: 100%; margin-left: 0; text-align: right; }

	.palette-bg { padding-top: 8vh; }
	.palette input { font-size: 16px; }
}

/* Tool fragments size their own fields inline (flex:2; min-width:14rem and
   similar), which is right on a desktop and overflows a phone. Two per row is
   the widest that fits, and !important is the only thing that beats an inline
   style. */
@media (max-width: 620px) {
	.row > .field {
		flex: 1 1 calc(50% - 0.3rem) !important;
		min-width: 0 !important;
	}
	.row > .field.wide, .row > .field:only-child {
		flex-basis: 100% !important;
	}
	.row { align-items: flex-start; }
}

@media (max-width: 420px) {
	.row > .field { flex-basis: 100% !important; }
	main { padding-left: max(0.85rem, env(safe-area-inset-left)); padding-right: max(0.85rem, env(safe-area-inset-right)); }
	h1 { font-size: 1.55rem; }
	.filters { gap: 0.3rem; }
	.chip { font-size: 0.74rem; padding: 0.34rem 0.6rem; }
}

/* Installed as an app there is no browser chrome, so the top bar has to clear
   the status bar itself. */
@media (display-mode: standalone) {
	.topbar { padding-top: max(0.55rem, env(safe-area-inset-top)); }
}

@media (min-width: 861px) {
	.scrim { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.bit, .bit:hover { transition: none; transform: none; }
	.rail, .scrim { transition: none; }
	* { scroll-behavior: auto !important; }
}
