:root {
  /* colours (Stitch theme) */
  --color-surface-container: #eeeef0;
  --color-tertiary: #5a5b5f;
  --color-on-primary: #ffffff;
  --color-tertiary-container: #737378;
  --color-on-tertiary-fixed-variant: #46464b;
  --color-secondary-fixed-dim: #c8c6c8;
  --color-surface-container-low: #f3f3f5;
  --color-surface-variant: #e2e2e4;
  --color-on-primary-container: #fcfbff;
  --color-on-primary-fixed-variant: #00458f;
  --color-on-error-container: #93000a;
  --color-error: #ba1a1a;
  --color-on-surface-variant: #414753;
  --color-secondary-container: #e2dfe1;
  --color-inverse-surface: #2f3132;
  --color-on-secondary-fixed: #1b1b1d;
  --color-error-container: #ffdad6;
  --color-secondary: #5f5e60;
  --color-secondary-fixed: #e4e2e4;
  --color-on-surface: #1a1c1d;
  --color-on-tertiary-container: #fcfaff;
  --color-on-secondary-fixed-variant: #474649;
  --color-background: #f9f9fb;
  --color-surface-container-highest: #e2e2e4;
  --color-surface-bright: #f9f9fb;
  --color-on-primary-fixed: #001b3f;
  --color-on-tertiary: #ffffff;
  --color-inverse-primary: #abc7ff;
  --color-tertiary-fixed-dim: #c7c6cb;
  --color-primary-fixed: #d7e2ff;
  --color-on-error: #ffffff;
  --color-on-secondary: #ffffff;
  --color-surface: #f9f9fb;
  --color-surface-container-high: #e8e8ea;
  --color-on-secondary-container: #636264;
  --color-primary-fixed-dim: #abc7ff;
  --color-on-tertiary-fixed: #1a1b1f;
  --color-primary: #0059b5;
  --color-surface-container-lowest: #ffffff;
  --color-on-background: #1a1c1d;
  --color-outline-variant: #c1c6d6;
  --color-inverse-on-surface: #f0f0f2;
  --color-outline: #717785;
  --color-surface-tint: #005cbb;
  --color-surface-dim: #d9dadc;
  --color-primary-container: #0071e3;
  --color-tertiary-fixed: #e3e2e7;
  /* product logo colours */
  --brand-docker: #2496ED;
  --brand-nodejs: #5FA04E;
  --brand-gitlab: #FC6D26;
  --brand-nextjs: #000000;
  --brand-postgresql: #336791;
  --brand-wordpress: #21759B;
  --brand-ghost: #15171A;
  --brand-magento: #EE672F;
  --brand-cpanel: #FF6C2C;
  --brand-supabase: #3ECF8E;
  --brand-woocommerce: #96588A;
  --brand-ubuntu: #E95420;
  --brand-debian: #D70A53;
  --brand-rocky: #10B981;
  --brand-windows: #0078D4;
  --brand-arch: #1793D1;
  --brand-alpine: #0D597F;
  --brand-amd: #ED1C24;
  --brand-intel: #0071C5;
  /* type: San Francisco on Apple devices, the system UI font elsewhere */
  --font-text: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI Variable Text", "Segoe UI", system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI Variable Display", "Segoe UI", system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  /* spacing */
  --margin: 3rem;
  --gutter-mobile: 1rem;
  --margin-mobile: 1.25rem;
  --space-xs: 0.25rem;
  --space-xl: 2.5rem;
  --space-md: 1rem;
  --space-sm: 0.5rem;
  --gutter: 1.5rem;
  --space-lg: 1.5rem;
  /* theme roles added for dark mode; in light they hold the colours the stylesheet used before */
  color-scheme: light;
  --color-surface-section: #ffffff;
  --color-surface-footer: #f3f3f5;
  --color-surface-selected: #ffffff;
  --color-on-selected-muted: #5a5b5f;
  --color-device: #2f3132;
  --color-on-device: #f0f0f2;
  --color-primary-solid: #0059b5;
  --color-header: rgb(255 255 255 / 0.8);
  --color-fill-soft: rgb(255 255 255 / 0.5);
  --color-fill-hover: rgb(255 255 255 / 0.8);
  --color-band-40: rgb(243 243 245 / 0.4);
  --color-band-50: rgb(243 243 245 / 0.5);
  --color-band-60: rgb(243 243 245 / 0.6);
  --color-tint-20: rgb(238 238 240 / 0.2);
  --color-tint-40: rgb(238 238 240 / 0.4);
  --color-tint-variant: rgb(226 226 228 / 0.6);
  --color-hairline: rgb(0 0 0 / 0.07);
  --color-border-soft: rgb(0 0 0 / 0.1);
  --color-border-strong: rgb(0 0 0 / 0.18);
  --color-border-default: #e5e7eb;
  --color-placeholder: #9ca3af;
  --color-field-edge: transparent;
  --shadow-field: none;
  --color-focus-soft: rgb(0 89 181 / 0.2);
  --color-solid-hover: #000000;
  /* VPS slider thumb under the pointer and pressed: the shades Chrome gave its own thumb */
  --color-slider-thumb-hover: #003d7d;
  --color-slider-thumb-active: #0075ed;
  --color-success: #059669;
  --color-success-strong: #047857;
  --color-success-container: #ecfdf5;
  --color-success-badge: #d1fae5;
  --color-on-success-badge: #065f46;
  --rgb-primary: 0 89 181;
  --rgb-primary-fixed: 215 226 255;
  --rgb-scrim: 47 49 50;
  --rgb-error: 186 26 26;
  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  --shadow-lg: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
  --shadow-popover: 0 12px 32px rgba(0, 0, 0, 0.08), 0 2px 6px rgba(0, 0, 0, 0.03);
  --shadow-popover-ring: 0 0 0 1px rgb(0 0 0 / 0.04), 0 12px 32px rgba(0, 0, 0, 0.08), 0 2px 6px rgba(0, 0, 0, 0.03);
  --shadow-card: 0 0 0 1px rgb(0 0 0 / 0.07), 0 1px 2px 0 rgb(0 0 0 / 0.04), 0 10px 28px -14px rgb(0 0 0 / 0.14);
  --shadow-card-featured: 0 0 0 1px rgb(0 0 0 / 0.07), 0 1px 2px 0 rgb(0 0 0 / 0.04), 0 18px 40px -18px rgb(0 0 0 / 0.24);
  --shadow-cta: 0 1px 2px rgba(0, 0, 0, 0.08);
  --shadow-hero: 0 30px 60px -20px rgba(26, 28, 29, 0.45);
  --shadow-window: 0 40px 80px -32px rgba(26, 28, 29, 0.22), 0 2px 8px rgba(26, 28, 29, 0.04);
  --shadow-dialog: 0 24px 64px rgba(26, 28, 29, 0.25);
  --shadow-sheet: -12px 0 40px rgba(26, 28, 29, 0.16);
  /* Ambient light ("Raking Light", site.css: Ambient light). Light is noon in a white room with one
     high window on the left: a warm key, a cool sky-lit shade, a sandstone floor bounce in the
     footer. Channels are "r g b" so each treatment sets its own alpha; --amb-gain scales every
     light for the theme and --amb-m softens them on phones. */
  --amb-key: 247 226 196;
  --amb-sky: 255 255 255;
  --amb-shade: 194 202 218;
  --amb-occlude: 104 112 128;
  --amb-bounce: 234 214 190;
  --amb-spill: 255 255 255;
  --amb-seam: #fbfbfc;
  --amb-band: #f5f5f7;
  --amb-edge: rgb(255 255 255 / 0.14);
  --amb-edge-side: rgb(255 255 255 / 0.05);
  --amb-sheen: rgb(255 255 255 / 0.06);
  --amb-grain: none;
  --amb-grain-blend: normal;
  --amb-gain: 1;
  --amb-m: 1;
}
@media (max-width: 640px) {
:root {
  --amb-m: 0.8;
}
}

/* Dark theme: the same roles, redrawn for the dark (html[data-theme="dark"], which the script at
   the top of head.php sets before the page paints). The page and its sections are the deepest
   cool charcoal; cards sit above them; fills, tracks and the selected cell of a control are
   lighter again, so depth reads in the dark the way it does in light. Elevation comes from
   lighter surfaces and hairline edges (the shadows' first ring) rather than from shadows. Text
   is soft white and two greys; the brand blue is lifted for text and kept for buttons. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --color-background: #0d0e11;
  --color-surface: #0d0e11;
  --color-surface-bright: #0d0e11;
  --color-surface-section: #111215;
  --color-surface-footer: #0a0b0d;
  --color-surface-container-lowest: #17181c;
  --color-surface-container-low: #1c1d22;
  --color-surface-container: #24252b;
  --color-surface-container-high: #2a2b31;
  --color-surface-container-highest: #32333a;
  --color-surface-variant: #32333a;
  --color-surface-dim: #3a3b42;
  --color-surface-selected: #46474f;
  --color-on-selected-muted: #bfc1c9;
  --color-device: #17181c;
  --color-on-device: #ececf0;
  --color-on-surface: #ececf0;
  --color-on-background: #ececf0;
  --color-on-surface-variant: #b4b7c0;
  --color-tertiary: #a6a8b1;
  --color-on-tertiary: #16171b;
  --color-tertiary-container: #5d5f67;
  --color-tertiary-fixed-dim: #45464e;
  --color-outline: #7a7e89;
  --color-outline-variant: #474952;
  --color-primary: #4f9df6;
  --color-primary-solid: #0063cc;
  --color-primary-container: #0071e3;
  --color-on-primary: #ffffff;
  --color-on-primary-container: #ffffff;
  --color-primary-fixed: #172a46;
  --color-primary-fixed-dim: #8fbaff;
  --color-on-primary-fixed: #d3e3ff;
  --color-on-primary-fixed-variant: #a9c8ff;
  --color-inverse-primary: #2d6fcf;
  --color-surface-tint: #4f9df6;
  --color-inverse-surface: #e6e7eb;
  --color-inverse-on-surface: #16171b;
  --color-error: #f2726b;
  --color-on-error: #1f0907;
  --color-error-container: #3b1618;
  --color-on-error-container: #ffb4ab;
  --color-header: rgb(13 14 17 / 0.78);
  --color-fill-soft: rgb(255 255 255 / 0.035);
  --color-fill-hover: rgb(255 255 255 / 0.07);
  --color-band-40: rgb(255 255 255 / 0.02);
  --color-band-50: rgb(255 255 255 / 0.03);
  --color-band-60: rgb(255 255 255 / 0.025);
  --color-tint-20: rgb(255 255 255 / 0.02);
  --color-tint-40: rgb(255 255 255 / 0.04);
  --color-tint-variant: rgb(255 255 255 / 0.05);
  --color-hairline: rgb(255 255 255 / 0.07);
  --color-border-soft: rgb(255 255 255 / 0.1);
  --color-border-strong: rgb(255 255 255 / 0.2);
  --color-border-default: rgb(255 255 255 / 0.08);
  --color-placeholder: #8a8d97;
  --color-field-edge: rgb(255 255 255 / 0.08);
  --shadow-field: inset 0 0 0 1px rgb(255 255 255 / 0.07);
  --color-focus-soft: rgb(79 157 246 / 0.6);
  --color-solid-hover: #c8c9d0;
  --color-slider-thumb-hover: #84bbf9;
  --color-slider-thumb-active: #1a7ff3;
  --color-success: #3ccf91;
  --color-success-strong: #5fdca6;
  --color-success-container: rgb(60 207 145 / 0.12);
  --color-success-badge: rgb(60 207 145 / 0.16);
  --color-on-success-badge: #8ef0c3;
  --rgb-primary: 79 157 246;
  --rgb-primary-fixed: 45 104 190;
  --rgb-scrim: 0 0 0;
  --rgb-error: 242 114 107;
  --shadow-xs: 0 0 0 1px rgb(255 255 255 / 0.06), 0 1px 2px 0 rgb(0 0 0 / 0.4);
  --shadow-md: 0 0 0 1px rgb(255 255 255 / 0.07), 0 6px 14px -4px rgb(0 0 0 / 0.55), 0 2px 4px -2px rgb(0 0 0 / 0.4);
  --shadow-lg: 0 0 0 1px rgb(255 255 255 / 0.07), 0 24px 40px -12px rgb(0 0 0 / 0.6);
  --shadow-popover: 0 0 0 1px rgb(255 255 255 / 0.08), 0 16px 40px rgb(0 0 0 / 0.55), 0 2px 6px rgb(0 0 0 / 0.35);
  --shadow-popover-ring: 0 0 0 1px rgb(255 255 255 / 0.08), 0 16px 40px rgb(0 0 0 / 0.55), 0 2px 6px rgb(0 0 0 / 0.35);
  --shadow-card: 0 0 0 1px rgb(255 255 255 / 0.07), 0 1px 2px 0 rgb(0 0 0 / 0.35), 0 12px 28px -14px rgb(0 0 0 / 0.6);
  --shadow-card-featured: 0 0 0 1px rgb(255 255 255 / 0.11), 0 1px 2px 0 rgb(0 0 0 / 0.35), 0 20px 40px -18px rgb(0 0 0 / 0.75);
  --shadow-cta: 0 1px 2px rgb(0 0 0 / 0.4);
  --shadow-hero: 0 0 0 1px rgb(255 255 255 / 0.07), 0 30px 60px -20px rgb(0 0 0 / 0.75);
  --shadow-window: 0 0 0 1px rgb(255 255 255 / 0.07), 0 40px 80px -32px rgb(0 0 0 / 0.75), 0 2px 8px rgb(0 0 0 / 0.3);
  --shadow-dialog: 0 0 0 1px rgb(255 255 255 / 0.08), 0 24px 64px rgb(0 0 0 / 0.6);
  --shadow-sheet: -1px 0 0 rgb(255 255 255 / 0.07), -12px 0 40px rgb(0 0 0 / 0.5);
  /* Ambient light after hours: no window, matte graphite; low tungsten lamps on alternating walls,
     a desaturated steel overhead, graphite corners, and the console as the one self-lit object
     (neutral, never blue). A fine grain, blended, keeps the soft falloffs from banding. */
  --amb-key: 226 192 150;
  --amb-sky: 152 162 180;
  --amb-shade: 9 10 13;
  --amb-bounce: 200 174 142;
  --amb-spill: 190 200 214;
  --amb-seam: #0f1013;
  --amb-band: #131417;
  --amb-card: #1a1b1f;
  --amb-card-nested: #1f2025;
  --amb-edge: rgb(255 255 255 / 0.06);
  --amb-edge-side: rgb(255 226 190 / 0.07);
  --amb-sheen: rgb(255 255 255 / 0.022);
  --amb-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='.17 .17 .17 0 .245 .17 .17 .17 0 .245 .17 .17 .17 0 .245 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E");
  --amb-grain-blend: overlay;
  --amb-gain: 1.8;
  /* logo colours too dark to read on charcoal */
  --brand-nextjs: #f2f2f4;
  --brand-ghost: #e6e6ea;
  --brand-alpine: #3393c9;
  --brand-postgresql: #6c9ccf;
  --brand-wordpress: #4aa0d0;
  --brand-intel: #2f8ad6;
  --brand-debian: #e8406f;
}

/* Icons: Material Symbols Outlined, served from assets/fonts/ with only the icons the site uses
   (see README). Each icon's name sits in data-icon, so CSS draws it and it is never read as page
   text, and every icon keeps its 1em square box, so nothing moves while the font loads. */
.material-symbols-outlined { font-family: 'Material Symbols Outlined'; font-weight: normal; font-style: normal; font-size: 24px; line-height: 1; letter-spacing: normal; text-transform: none; display: inline-block; white-space: nowrap; word-wrap: normal; direction: ltr; -webkit-font-feature-settings: 'liga'; font-feature-settings: 'liga'; -webkit-font-smoothing: antialiased; width: 1em; overflow: clip; }
.material-symbols-outlined::before { content: attr(data-icon); }

/* Reset: consistent defaults across browsers */
*, ::after, ::before { box-sizing: border-box; border-width: 0; border-style: solid; border-color: var(--color-border-default); }
:host, html { line-height: 1.5; -webkit-text-size-adjust: 100%; -moz-tab-size: 4; tab-size: 4; font-family: var(--font-text); font-feature-settings: normal; font-variation-settings: normal; -webkit-tap-highlight-color: transparent; }
body { margin: 0; line-height: inherit; }
hr { height: 0; color: inherit; border-top-width: 1px; }
abbr:where([title]) { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; }
h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; }
a { color: inherit; text-decoration: inherit; }
b, strong { font-weight: bolder; }
code, kbd, pre, samp { font-family: var(--font-mono); font-feature-settings: normal; font-variation-settings: normal; font-size: 1em; }
small { font-size: 80%; }
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sub { bottom: -.25em; }
sup { top: -.5em; }
table { text-indent: 0; border-color: inherit; border-collapse: collapse; }
button, input, optgroup, select, textarea { font-family: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 100%; font-weight: inherit; line-height: inherit; letter-spacing: inherit; color: inherit; margin: 0; padding: 0; }
button, select { text-transform: none; }
button, input:where([type=button]), input:where([type=reset]), input:where([type=submit]) { -webkit-appearance: button; background-color: transparent; background-image: none; }
:-moz-focusring { outline: auto; }
:-moz-ui-invalid { box-shadow: none; }
progress { vertical-align: baseline; }
::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; }
[type=search] { -webkit-appearance: textfield; outline-offset: -2px; }
::-webkit-search-decoration { -webkit-appearance: none; }
::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; }
summary { display: list-item; }
blockquote, dd, dl, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { margin: 0; }
fieldset { margin: 0; padding: 0; }
legend { padding: 0; }
menu, ol, ul { list-style: none; margin: 0; padding: 0; }
dialog { padding: 0; }
textarea { resize: vertical; }
input::placeholder, textarea::placeholder { opacity: 1; color: var(--color-placeholder); }
[role=button], button { cursor: pointer; }
:disabled { cursor: default; }
audio, canvas, embed, iframe, img, object, svg, video { display: block; vertical-align: middle; }
img, video { max-width: 100%; height: auto; }
[hidden]:where(:not([hidden=until-found])) { display: none !important; }

@keyframes pulse { 50%{opacity:.5} }
body { background-color: var(--color-background); font-family: var(--font-text); color: var(--color-on-surface); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
.has-fixed-header { scroll-padding-top: 3.5rem; }
