vitrine

style.css

/* vitrine stylesheet.  Embedded in the binary; served at /-/style.css. */

:root {
	--ink: #24292f;
	--ink-soft: #57606a;
	--accent: #0a5fa4;
	--rule: #d0d7de;
	--paper: #fdfdfc;
	--well: #f3f5f7;
	--well-edge: #c9d1d9;
	--tip: #c99000;
	--success: #1a7f37;
	--todo: #8250df;
	--warning: #ef7c00;
	--danger: #cf222e;
}

/* Dark mode follows the OS/browser preference; there is no in-page toggle
   (vitrine ships no JavaScript, so there is nowhere to store one).
   Every color below is picked to clear WCAG AA (4.5:1) against --paper;
   see the vitrine.meta worklog on dark mode for the measurements. */
@media (prefers-color-scheme: dark) {
	:root {
		--ink: #e6edf3;
		--ink-soft: #9198a1;
		--rule: #30363d;
		--paper: #0d1117;
		--well: #161b22;
		--well-edge: #30363d;
		--tip: #d29922;
		--success: #3fb950;
		--todo: #a371f7;
		--warning: #f0883e;
		--danger: #f85149;
	}
}

body {
	font-family: sans-serif;
	color: var(--ink);
	background: var(--paper);
	max-width: 56rem;
	margin: 1rem auto;
	padding: 0 1rem;
	line-height: 1.5;
}

a { color: var(--accent); }

nav {
	border-bottom: 2px solid var(--accent);
	padding-bottom: .5rem;
	margin-bottom: 1rem;
}
nav .raw {
	float: right;
	font-size: .85rem;
	border: 1px solid var(--rule);
	border-radius: .25rem;
	padding: .1rem .5rem;
	text-decoration: none;
}
nav .raw:hover { background: var(--well); }

/* Host theme name: names the host whose accent color this page wears,
   so the color never has to carry that meaning alone. */
nav .theme {
	font-size: .75rem;
	color: var(--accent);
	margin-left: .25rem;
}

ul.listing { list-style: none; padding-left: 1.5rem; }
ul.listing li { padding: .15rem 0; }

iframe.passthrough {
	width: 100%;
	height: 75vh;
	border: 1px solid var(--well-edge);
	border-radius: .25rem;
	background: white;
}

/* Headings sit flush left; all other article content is inset,
   so headings read as structure at a glance. */
article > * { margin-left: 1.5rem; }
article > h1, article > h2, article > h3,
article > h4, article > h5, article > h6 { margin-left: 0; }

article h1, article h2 {
	border-bottom: 1px solid var(--rule);
	padding-bottom: .2rem;
}
article h1 { color: var(--accent); }

/* Chainlink anchors: subtle until the heading is hovered. */
a.anchor {
	font-size: .7em;
	text-decoration: none;
	margin-left: .4rem;
	opacity: 0;
}
h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor,
h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor,
a.anchor:focus { opacity: .6; }

/* Code blocks: inset further than prose, bordered, in a well. */
article pre {
	margin-left: 3rem;
	background: var(--well);
	border: 1px solid var(--well-edge);
	border-left: 3px solid var(--accent);
	border-radius: .25rem;
	padding: .6rem .8rem;
	overflow-x: auto;
}
article code {
	background: var(--well);
	border-radius: .2rem;
	padding: .05rem .25rem;
}
article pre code { background: none; padding: 0; }

article blockquote {
	border-left: 3px solid var(--rule);
	color: var(--ink-soft);
	padding-left: .8rem;
}

article table { border-collapse: collapse; }
article th, article td {
	border: 1px solid var(--rule);
	padding: .2rem .5rem;
}
article th { background: var(--well); }

/* Callouts: :::type admonition boxes.
   Each type carries one accent hue in --callout, and the base box derives its
   tinted fill and border from that hue with color-mix, so a single value drives
   the whole look (info and note simply inherit the per-host --accent).
   --callout-icon is the emoji shown before a title, following this repo's
   emoji-as-icon idiom (see the heading chainlink); it rides the title, so a
   title-less callout shows no icon. */
article .callout {
	--callout: var(--accent);
	--callout-fill: 12%; /* how much of --callout tints the box background */
	margin-top: 1.25rem;
	margin-bottom: 1.25rem;
	padding: .7rem 1rem;
	border: 1px solid color-mix(in srgb, var(--callout) 45%, var(--well-edge));
	border-left: 3px solid var(--callout);
	border-radius: .5rem;
	background: color-mix(in srgb, var(--callout) var(--callout-fill), var(--paper));
	box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
}
/* The children are already inset by "article > *"; inside the box they
   should sit flush to its padding instead. */
article .callout > * { margin-left: 0; }
article .callout-title {
	margin: 0 0 .4rem;
	font-weight: bold;
	font-size: .95rem;
	text-transform: uppercase;
	letter-spacing: .03em;
	color: var(--callout);
}
/* The icon rides the title via --callout-icon.  Only the known types below set
   it, so an unknown type shows a clean icon-less box rather than a misleading
   glyph; a title-less callout shows no icon at all. */
article .callout-title::before {
	content: var(--callout-icon, "");
	margin-right: .45rem;
}

/* Per-type accent hues and icons, for the canonical type set only;
   warn is folded onto warning by the normalizer before it reaches the class.
   info and note keep the per-host --accent.  An unknown type matches none of
   these and falls back to the neutral base box above, still readable. */
article .callout-info,
article .callout-note { --callout-icon: "\2139\FE0F"; }  /* information source, theme color */
article .callout-tip { --callout: var(--tip); --callout-icon: "\1F4A1"; }     /* light bulb, sunflower gold */
article .callout-success { --callout: var(--success); --callout-icon: "\2705"; }  /* check mark, green */
article .callout-todo { --callout: var(--todo); --callout-icon: "\1F6A7"; }    /* construction sign, purple */
article .callout-warning { --callout: var(--warning); --callout-fill: 18%; --callout-icon: "\26A0\FE0F"; } /* warning sign, orange (weaker hue, so tinted harder) */
article .callout-danger { --callout: var(--danger); --callout-icon: "\1F9E8"; }   /* firecracker, red */
article .callout-reject { --callout: var(--danger); --callout-icon: "\274C"; }    /* cross mark, red */


/* Diagrams: server-rendered inline SVG from ```dot fenced blocks.
   Inset like a code block and centered; a wide diagram scales down to the
   content width rather than overflowing, while a small one keeps its size. */
article .diagram {
	margin: 1.25rem 0 1.25rem 3rem;
	text-align: center;
}
article .diagram svg {
	max-width: 100%;
	height: auto;
}
/* Graphviz always draws on an opaque white canvas with black ink, regardless
   of the page theme (DOT has no notion of a page dark mode).
   Inverting lightness while rotating hue back into place turns that white
   canvas dark and keeps colored edges/nodes close to their original hue,
   without needing to parse or rewrite the SVG's own fill/stroke attributes. */
@media (prefers-color-scheme: dark) {
	article .diagram svg {
		filter: invert(0.9) hue-rotate(180deg);
	}
}

/* A diagram that failed to render echoes its source in a bordered well,
   flagged in the danger hue so the failure is visible at a glance. */
article .diagram-error {
	text-align: left;
	border: 1px solid var(--danger);
	border-radius: .25rem;
	background: color-mix(in srgb, var(--danger) 8%, var(--paper));
	padding: .4rem .8rem;
}
article .diagram-error-note {
	margin: .2rem 0;
	font-weight: bold;
	color: var(--danger);
}
article .diagram-error pre { margin-left: 0; }

display/style.css · 7.0 KiB · a92ee56422