/* ──────────────────────────────────────────────────────────────────────────
   DMInspired landing page — "Terminal Canopy"
   Mobile-first. Dark only. See INDEX-REVAMP.md §5, §8, §10.

   Deliberately does NOT touch main.css, which the current index.php still
   uses (INDEX-REVAMP.md §16.2).
   ────────────────────────────────────────────────────────────────────────── */

:root {
	/* Contrast measured against --bg. See INDEX-REVAMP.md §10.6. */
	--bg:        #07090b;
	--ink:       #e8d5c4;   /* 14.0:1 — body text                        */
	--muted:     #9a8878;   /*  5.9:1 — de-emphasised TEXT               */
	--dim:       #6b5a4d;   /*  3.0:1 — borders + decoration ONLY        */
	--accent:    #e8650a;   /*  6.0:1 — cursor, hover, focus, active     */
	--accent-lo: #8a3d06;
	--glow:      #ffb067;

	--mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
	        "DejaVu Sans Mono", "Liberation Mono", monospace;

	--gutter: 16px;
	--rule: 1px solid var(--dim);

	/* Enables the 0 → auto block-size transition on ::details-content. */
	interpolate-size: allow-keywords;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
	margin: 0;
	min-height: 100dvh;           /* not 100vh — §10.3                    */
	background: var(--bg);
	color: var(--ink);
	font-family: var(--mono);
	font-size: 1rem;              /* 16px floor on phones — §10.5         */
	line-height: 1.5;
	display: flex;
	flex-direction: column;
}

/* Screen-reader-only text. Used for the ASCII wordmark's real name and for
   input labels (§6, §8.3). */
.sr-only {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ── Canvas ───────────────────────────────────────────────────────────────
   Decorative, aria-hidden, behind everything. Sized by CSS before first
   paint so it never causes a shift. */
#canopy {
	position: fixed;
	inset: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	pointer-events: none;
}

/* ── Shell ─────────────────────────────────────────────────────────────── */
#wrapper {
	position: relative;
	z-index: 1;
	flex: 1;
	display: flex;
	flex-direction: column;
	/* Anchored to the top, NOT centred: expanding the directory must not
	   move the logo. See §4. */
	justify-content: flex-start;
	padding: 12vh var(--gutter) 0;
}

#main {
	width: 100%;
	max-width: 100%;
	margin-inline: auto;
}

/* ── Hero ──────────────────────────────────────────────────────────────── */
#header { margin-bottom: 2rem; }

.logo {
	margin: 0 0 1rem;
	font-size: clamp(0.7rem, 3.1vw, 1.15rem);
	font-weight: 400;
	color: var(--accent);
	overflow: hidden;             /* art is 20ch, but never let it scroll */
}

/* `white-space: pre` is scoped to the art itself, NOT the <h1>. On the
   parent it would also preserve the source indentation between the tags,
   which shifts the first row right and breaks the alignment. */
.logo-art {
	display: block;
	white-space: pre;
	/* Exactly 1. In this figlet face the underscores ARE each letter's top
	   stroke and are meant to sit directly on the row below; any extra
	   leading pulls the letters apart. */
	line-height: 1;
}

.wordmark {
	display: block;
	margin-top: 0.9rem;
	font-size: 0.875rem;
	letter-spacing: 0.42em;       /* styled, not literal spaces — §15.1   */
	color: var(--ink);
}

.tagline {
	margin: 0;
	max-inline-size: 65ch;        /* §10.3                                */
	color: var(--muted);
	font-size: 1rem;
}

.tagline .sep { color: var(--dim); margin: 0 0.4em; }

/* ── Disclosure ────────────────────────────────────────────────────────── */
.tools {
	border: var(--rule);
	background: rgba(7, 9, 11, 0.72);
}

/* ── The command line ──────────────────────────────────────────────────── */
/* The prompt row IS the input. Not a <summary>: an <input> inside one
   fights it for clicks and for Space/Enter. §8.1 */
.tools__cli {
	display: flex;
	align-items: center;
	gap: 0.6ch;
	min-height: 48px;             /* primary control — §10.4              */
	padding: 0 0.8rem;
	margin: 0;
}

.tools__cli:hover { background: rgba(232, 101, 10, 0.04); }

/* The caret is the design; show focus on the row, not a box round the input. */
.tools__cli:focus-within { box-shadow: inset 0 -1px 0 var(--accent); }

.tools__cli input {
	flex: 1;
	min-width: 0;
	min-height: 32px;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--ink);
	font-family: inherit;
	font-size: 1rem;              /* ≥16px or iOS zooms on focus — §10.3  */
	line-height: 1.5;
}
/* The placeholder carries the old summary text, so at rest the row still
   reads "dmi@dminspired:~$ ls ~/tools". It must look like a typed command,
   not like grey placeholder furniture. */
.tools__cli input::placeholder { color: var(--muted); opacity: 1; }
.tools__cli input:focus { outline: none; }
.tools__cli input:focus-visible { outline: none; }
.tools__cli input::-webkit-search-cancel-button { display: none; }

.prompt { color: var(--accent-lo); white-space: nowrap; }
.cmd    { color: var(--ink); white-space: nowrap; }
.count  { color: var(--dim); font-size: 0.75rem; }

/* Under ~400px the prompt, the command, the count and the chevron don't fit
   on one line. The host prompt is decoration (aria-hidden), so it goes
   first and "ls ~/tools [22] ▸" still reads as a command. */
@media (max-width: 400px) {
	.tools__cli .prompt { display: none; }
}

/* ── Chevron ───────────────────────────────────────────────────────────── */
.chev {
	flex: none;
	display: grid;
	place-items: center;
	min-width: 32px;
	min-height: 32px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--accent);
	font: inherit;
	cursor: pointer;
}
.chev__g {
	display: block;
	transition: transform 150ms cubic-bezier(.2, 0, 0, 1);
}
.tools[data-open] .chev__g { transform: rotate(90deg); }
.chev:hover { color: var(--glow); }
.chev:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* ── Panel ─────────────────────────────────────────────────────────────── */
/* `visibility` rather than `content-visibility`: it is universally
   supported, it reliably removes the collapsed links from the tab order,
   and it transitions discretely — flipping to visible at the START of an
   open and to hidden at the END of a close, which is exactly right. */
.tools__panel {
	contain: layout paint;
	border-top: var(--rule);
	padding: 0 0.8rem;
	height: 0;
	overflow: clip;
	visibility: hidden;
	/* closing: faster, accelerating */
	transition: height 140ms cubic-bezier(.4, 0, 1, 1),
	            padding 140ms cubic-bezier(.4, 0, 1, 1),
	            visibility 140ms;
}

.tools[data-open] .tools__panel {
	height: auto;
	visibility: visible;
	padding: 0.6rem 0.8rem 0.8rem;
	/* opening: slower, decelerating */
	transition-duration: 200ms;
	transition-timing-function: cubic-bezier(.2, 0, 0, 1);
}

/* No JavaScript: the panel must stay open, or the 22 tools become
   unreachable. The inline script in <head> swaps no-js for js before first
   paint, so a JS visitor never sees this state. §8.1 */
.no-js .tools__panel {
	height: auto;
	visibility: visible;
	padding: 0.6rem 0.8rem 0.8rem;
	transition: none;
}
.no-js .chev { display: none; }

.tools__resolve {
	color: var(--accent);
	font-size: 0.875rem;
	white-space: nowrap;
}

.tools__tally {
	color: var(--dim);
	font-size: 0.75rem;
	white-space: nowrap;
}

/* ── Grid ──────────────────────────────────────────────────────────────── */
.tools__grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	/* Column count falls out of the width; only the min changes per tier. */
	grid-template-columns: repeat(auto-fill, minmax(11ch, 1fr));
	gap: 2px 1.5ch;
}

.tools__grid a {
	display: block;
	padding-block: 0.7rem;        /* 44px row on phones, via padding, not
	                                 font size — §10.4                    */
	color: var(--ink);
	text-decoration: none;
	line-height: 1.3;
	overflow-wrap: anywhere;
}

.tools__grid a:hover,
.tools__grid a:focus-visible { color: var(--accent); }

.tools__grid a:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* Blurb: a second line inside each cell by default, because a coarse
   pointer has no hover to reveal it. Moved to the status line only where
   hover genuinely exists. §10.2 */
.blurb {
	display: block;
	color: var(--muted);
	font-size: 0.875rem;
	line-height: 1.3;
}

/* Filtered out: --muted, never --dim. Keeps its cell, so nothing reflows. */
.tools__grid li[data-off] a { color: var(--muted); }
.tools__grid li[data-off] .blurb { color: var(--dim); }
.tools__grid li[data-off] { pointer-events: none; }

/* Whole grid steps back when sub-page results are showing. §9.4 */
.tools__grid[data-recede] { opacity: 0.45; }

/* First-open row reveal. Disabled on phones and under reduced motion.
   --i is set per item in index2.php; 22 items × 8ms ≈ 176ms total, which
   reads as a row-by-row sweep without becoming a tax on every open. */
.tools[data-stagger] .tools__grid li {
	animation: rowIn 180ms cubic-bezier(.2, 0, 0, 1) backwards;
	animation-delay: calc(var(--i, 0) * 8ms);
}
@keyframes rowIn {
	from { opacity: 0; transform: translateY(-2px); }
	to   { opacity: 1; transform: none; }
}

/* ── Results ───────────────────────────────────────────────────────────── */
.tools__results {
	list-style: none;
	margin: 0 0 0.8rem;
	padding: 0;
}

.tools__results a {
	display: flex;
	gap: 1ch;
	align-items: baseline;
	min-height: 44px;
	padding-block: 0.5rem;
	color: var(--ink);
	text-decoration: none;
	line-height: 1.3;
}
.tools__results a:hover,
.tools__results a:focus-visible { color: var(--accent); }
.tools__results a:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}
.tools__results .app  { color: var(--muted); }
.tools__results .leaf { color: inherit; }
.tools__results mark {
	background: none;
	color: var(--accent);
	font-weight: 700;
}

.tools__more {
	min-height: 24px;
	padding: 0.3rem 0;
	border: 0;
	background: none;
	color: var(--muted);
	font-family: inherit;
	font-size: 0.875rem;
	cursor: pointer;
	text-align: left;
}
.tools__more:hover { color: var(--accent); }
.tools__more:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

.tools__status {
	margin: 0.6rem 0 0;
	min-height: 1.5em;
	color: var(--muted);
	font-size: 0.875rem;
}

.tools__hint { color: var(--dim); }

/* ── Footer ────────────────────────────────────────────────────────────── */
/* In normal flow, NOT fixed: a fixed footer can cover a focused link in the
   expanded grid — WCAG 2.2 focus-not-obscured. §10.3 */
#footer {
	position: relative;
	z-index: 1;
	margin-top: 3rem;
	padding: 1rem var(--gutter) max(12px, env(safe-area-inset-bottom));
	border-top: var(--rule);
	color: var(--muted);
	font-size: 0.75rem;
}

#footer .inner {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.5ch;
	align-items: center;
	max-width: 100%;
	margin-inline: auto;
}

/* Pause control for the canvas. Required, not optional — both motion
   skills mandate a stop control for ambient motion over 5s. §11 */
.motion-toggle {
	min-height: 24px;
	padding: 0.2rem 0.4rem;
	margin-inline-start: auto;
	border: var(--rule);
	background: none;
	color: var(--muted);
	font-family: inherit;
	font-size: 0.75rem;
	cursor: pointer;
}
.motion-toggle:hover { color: var(--accent); border-color: var(--accent-lo); }
.motion-toggle:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}
.motion-toggle[hidden] { display: none; }

/* ──────────────────────────────────────────────────────────────────────────
   Tablet — §10.2
   ────────────────────────────────────────────────────────────────────────── */
@media (min-width: 768px) {
	:root { --gutter: 24px; }

	#main   { max-width: 640px; }
	#footer .inner { max-width: 640px; }

	.logo     { font-size: 1rem; }
	.tagline  { font-size: 1.125rem; }

	.tools__grid { grid-template-columns: repeat(auto-fill, minmax(13ch, 1fr)); }
	.tools__grid a { padding-block: 0.45rem; }
}

/* ──────────────────────────────────────────────────────────────────────────
   Desktop — §10.2
   ────────────────────────────────────────────────────────────────────────── */
@media (min-width: 1024px) {
	#main   { max-width: 720px; }
	#footer .inner { max-width: 720px; }

	.tools__grid { grid-template-columns: repeat(auto-fill, minmax(14ch, 1fr)); }
	.tools__grid a { padding-block: 0.35rem; font-size: 0.9375rem; }
}

@media (min-width: 1440px) {
	/* Cap at 5 columns rather than letting it sprawl. */
	.tools__grid { grid-template-columns: repeat(auto-fill, minmax(13ch, 1fr)); max-width: 72ch; }
}

/* ──────────────────────────────────────────────────────────────────────────
   Pointer capability, not width: a touchscreen laptop is wide AND
   hoverless, so the blurb placement keys off hover, not a breakpoint. §10.2
   ────────────────────────────────────────────────────────────────────────── */
@media (hover: hover) and (pointer: fine) {
	.tools__grid .blurb {
		position: absolute;
		width: 1px; height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}
}

/* ──────────────────────────────────────────────────────────────────────────
   Short landscape phones: reclaim the hero's vertical padding. §10.3
   ────────────────────────────────────────────────────────────────────────── */
@media (orientation: landscape) and (max-height: 500px) {
	#wrapper { padding-top: 4vh; }
	#header  { margin-bottom: 1rem; }
	.logo    { margin-bottom: 0.5rem; }
}

/* ──────────────────────────────────────────────────────────────────────────
   Reduced motion. Targeted, not a global wipe: the chevron must still
   change state, and the canvas still renders one static frame. §11
   ────────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
	.chev { transition: none; }

	@supports selector(details::details-content) {
		.tools::details-content,
		.tools[open]::details-content { transition: none; }
	}

	.tools[data-stagger] .tools__grid li { animation: none; }
}
