/* ===========================================================================
   jonshaulis.com — "Console" theme
   ===========================================================================
   Reads like a terminal session: prompt lines, monospace metadata, 2px section
   rules, zero border radius, no shadows, no gradients (except the fade on a
   collapsed code block).

   Colour discipline: the purple accent is for chrome only. Blue and green live
   exclusively inside code, so syntax highlighting reads as meaning rather than
   decoration and nothing competes with it.

   Grids draw their own rules: `gap:1px; background:var(--soft)` with each cell
   painted `var(--bg)`. That is what produces the visible 1px grid without
   per-cell borders.
   =========================================================================== */

@import url('/fonts/fonts.css');

/* --- tokens: light is the base, dark overrides --------------------------- */
:root {
  --bg: #f4f6fa;
  --surface: #e9edf3;
  --text: #131722;
  --muted: #4b5567;
  --accent: #7c3aed;
  --accent-ink: #6d28d9;
  --on-accent: #f4f6fa;
  --divider: rgba(19, 23, 34, 0.4);
  --soft: rgba(19, 23, 34, 0.12);

  /* Code is a dark terminal in both themes - deliberate, per the design. */
  --code-bg: #0f1117;
  --code-text: #e8eaf0;
  --code-kw: #c084fc;
  --code-str: #4ade80;
  --code-id: #7dd3fc;
  --code-cm: #7c8494;
  --code-rule: rgba(232, 234, 240, 0.14);

  --sans: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --gutter: 40px;
  --maxw: 1180px;
}

html[data-theme="dark"] {
  --bg: #0f1117;
  --surface: #171a23;
  --text: #e8eaf0;
  --muted: #9aa3b5;
  --accent: #c084fc;
  --accent-ink: #c084fc;
  --on-accent: #0f1117;
  --divider: rgba(232, 234, 240, 0.35);
  --soft: rgba(232, 234, 240, 0.12);
  --code-bg: #0a0c11;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-weight: 800; margin: 0; letter-spacing: -0.02em; }
p { margin: 0; }
img { max-width: 100%; height: auto; }

a { color: inherit; text-decoration: none; }
a:hover { color: var(--accent-ink); }

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

.container { max-width: var(--maxw); margin: 0 auto; }

.skip-link {
  position: absolute;
  left: -9999px;
  background: var(--accent);
  color: var(--on-accent);
  padding: 10px 14px;
  font-weight: 800;
}
.skip-link:focus { left: 8px; top: 8px; z-index: 50; }

/* --- shared chrome ------------------------------------------------------- */
.site-header { border-bottom: 2px solid var(--divider); }
/* The row is the inner .header-row; .site-header only carries the rule. */
.site-header .header-row {
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 18px var(--gutter);
  max-width: none;
}

.brand {
  font-weight: 800;
  font-size: 18px;
  letter-spacing: -0.01em;
  margin-right: auto;
  text-transform: uppercase;
}

.site-nav { display: flex; align-items: center; gap: 24px; font-size: 14px; }
.site-nav a[aria-current="page"] { color: var(--accent-ink); }

#theme-toggle {
  font-family: var(--mono);
  font-size: 12px;
  background: transparent;
  color: var(--text);
  border: 1px solid var(--divider);
  padding: 6px 10px;
  cursor: pointer;
}
#theme-toggle:hover { background: var(--soft); }

.nav-toggle { display: none; }

.site-footer {
  margin-top: 56px;
  padding: 18px var(--gutter);
  border-top: 2px solid var(--divider);
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
}
.footer-row { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.footer-row a:hover { color: var(--accent-ink); }

/* Decorative terminal prompt that opens each page. */
.prompt {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--muted);
  margin: 0;
}
.prompt b { color: var(--text); font-weight: 400; }

.kicker {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.07em;
}

/* --- buttons ------------------------------------------------------------- */
.btn {
  display: inline-block;
  font-family: var(--sans);
  font-weight: 800;
  font-size: 13px;
  padding: 10px 16px;
  border: 1px solid transparent;
  cursor: pointer;
  text-align: left;
}
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { background: #a855f7; color: var(--on-accent); }
html:not([data-theme="dark"]) .btn-primary:hover { background: #6d28d9; }
.btn-secondary { border-color: var(--divider); color: var(--text); background: transparent; }
.btn-secondary:hover { background: var(--soft); color: var(--text); }

/* --- cell grids ---------------------------------------------------------- */
.cellgrid {
  display: grid;
  gap: 1px;
  background: var(--soft);
  border: 1px solid var(--soft);
}
.cellgrid > * { background: var(--bg); }

/* --- home ---------------------------------------------------------------- */
.home-intro { padding: 56px var(--gutter) 0; }
/* Title and tagline each hold one line on desktop. The clamp scales the
   type down rather than wrapping; below 900px wrapping is allowed, because
   "Senior Principal Data Architect Engineer" on one line at phone width
   would be unreadably small. */
.home-intro h1 {
  margin: 18px 0 0;
  font-size: clamp(28px, 4.1vw, 48px);
  line-height: 1.05;
  letter-spacing: -0.028em;
  max-width: none;
}
.home-tagline {
  margin: 14px 0 0;
  font-size: clamp(14px, 1.45vw, 18px);
  line-height: 1.5;
  color: var(--muted);
  max-width: none;
}

@media (min-width: 900px) {
  .home-intro h1,
  .home-tagline { white-space: nowrap; }
}

/* Hero query panel: the tagline made structural. Its result set is the
   "start here" post list, so the joke doubles as navigation. */
.hero-query {
  margin: 40px var(--gutter) 0;
  background: var(--code-bg);
  border: 1px solid var(--soft);
  color: var(--code-text);
}
.hero-query-head { padding: 22px 24px 18px; border-bottom: 1px solid var(--code-rule); }
.hero-query-prompt { font-family: var(--mono); font-size: 13px; color: var(--code-cm); margin: 0 0 10px; }
.hero-query-sql {
  margin: 0;
  font-family: var(--mono);
  font-size: 22px;
  line-height: 1.5;
  white-space: pre-wrap;
}
.hero-query-sql .kw { color: var(--code-kw); }
.hero-query-sql .str { color: var(--code-str); }
.hero-query-sql .num { color: var(--code-id); }

.result-rows { padding: 0 24px; }
.result-head,
.result-row {
  display: grid;
  grid-template-columns: 44px 1fr 150px 110px;
  gap: 18px;
  align-items: start;
}
.result-head {
  padding: 12px 0;
  border-bottom: 1px solid var(--code-rule);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--code-cm);
  letter-spacing: 0.06em;
}
.result-row {
  padding: 15px 0;
  border-bottom: 1px solid var(--code-rule);
  color: var(--code-text);
}
.result-row:hover .result-title { color: var(--code-kw); }
.result-idx, .result-date { font-family: var(--mono); font-size: 12px; color: var(--code-cm); }
.result-date { text-align: right; }
.result-title { font-weight: 600; font-size: 17px; line-height: 1.3; }
.result-cat { font-family: var(--mono); font-size: 12px; color: var(--code-id); }
.result-foot {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 24px 16px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--code-cm);
  flex-wrap: wrap;
}
.result-foot a { color: var(--code-kw); }

/* Status strip: states plainly that the archive is finished but tended, which
   is more honest than hiding a 2020 end date. */
.status-strip {
  margin-top: 40px;
  border-top: 2px solid var(--divider);
  border-bottom: 2px solid var(--divider);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--soft);
}
.status-cell { background: var(--bg); padding: 24px var(--gutter); }
.status-cell .kicker { display: block; margin-bottom: 10px; }
.status-value {
  font-weight: 800;
  font-size: 17px;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}
.status-square { width: 10px; height: 10px; background: var(--accent); flex: none; }
.status-cell p { font-size: 14px; color: var(--muted); line-height: 1.55; }
.status-actions { display: flex; gap: 10px; flex-wrap: wrap; }

.home-main { display: grid; grid-template-columns: 2fr 1fr; gap: 1px; background: var(--soft); }
.home-recent, .home-side { background: var(--bg); padding: 32px var(--gutter) 48px; }

.section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
}
.section-header h2 { font-size: 26px; }
.section-header a { font-size: 13px; font-weight: 600; color: var(--accent-ink); }

.post-grid { grid-template-columns: repeat(2, 1fr); }
.post-tile {
  padding: 20px;
  min-height: 170px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.post-tile:hover { background: var(--surface); }
.tile-meta {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--mono);
  font-size: 11px;
}
.tile-cat { color: var(--accent-ink); }
.tile-date { color: var(--muted); }
.post-tile h3 { font-size: 19px; line-height: 1.22; letter-spacing: -0.01em; }
.post-tile p { font-size: 13px; line-height: 1.5; color: var(--muted); flex: 1; }

.home-side h2 { font-size: 18px; margin-bottom: 8px; }
.side-list { list-style: none; margin: 0 0 32px; padding: 0; border-top: 2px solid var(--divider); }
.side-list li { border-bottom: 1px solid var(--soft); }
.side-list li > a {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  font-size: 14px;
  font-weight: 600;
}
.side-list .count { font-family: var(--mono); font-size: 12px; color: var(--muted); font-weight: 400; }
.year-grid { grid-template-columns: repeat(4, 1fr); margin-top: 8px; }
.year-cell { padding: 12px; }
.year-cell:hover { background: var(--surface); }
.year-cell .y { font-family: var(--mono); font-size: 13px; font-weight: 600; display: block; }
.year-cell .n { font-size: 12px; color: var(--muted); }

@media (max-width: 1080px) {
  .status-strip { grid-template-columns: 1fr; }
  .home-main { grid-template-columns: 1fr; }
  .result-head, .result-row { grid-template-columns: 36px 1fr 96px; }
  .result-cat { display: none; }
  .home-intro h1 { font-size: 34px; }
  .hero-query-sql { font-size: 17px; }
}
@media (max-width: 720px) {
  .post-grid { grid-template-columns: 1fr; }
  .home-intro h1 { font-size: 28px; }
}

/* --- post ---------------------------------------------------------------- */
.post-head { padding: 44px var(--gutter) 32px; border-bottom: 2px solid var(--divider); }
.post-head h1 {
  /* Spec called for 48px/1.05. Titles here are routinely 12+ words - "Identify
     and resolve conversion failed when converting the varchar value..." - and
     display leading makes those cramped. Eased to 40px/1.12. */
  margin: 18px 0 0;
  font-size: 40px;
  line-height: 1.12;
  letter-spacing: -0.02em;
  max-width: 24ch;
  text-wrap: pretty;
}
.post-dek {
  margin: 16px 0 0;
  font-size: 18px;
  line-height: 1.5;
  color: var(--muted);
  max-width: 60ch;
}
.post-meta {
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  margin-top: 18px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
}
.post-meta .cat { color: var(--accent-ink); }

.series-strip {
  margin: 0 var(--gutter);
  border-bottom: 1px solid var(--soft);
  display: grid;
  grid-template-columns: auto 1fr;
}
.series-label {
  min-width: 220px;
  padding: 16px 20px 16px 0;
  border-right: 1px solid var(--soft);
}
.series-label .name { font-weight: 800; font-size: 15px; display: block; margin-top: 4px; }
.series-parts { display: grid; }
.series-part {
  padding: 14px 16px;
  border-right: 1px solid var(--soft);
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--muted);
}
.series-part:hover { background: var(--surface); }
.series-part .t { font-size: 13px; font-weight: 600; }
.series-part.is-current { color: var(--text); border-bottom: 2px solid var(--accent); }

.post-layout { display: grid; grid-template-columns: 1fr; gap: 48px; padding: 40px var(--gutter) 0; }
.post-layout.has-toc { grid-template-columns: 1fr 260px; }

.post-content { max-width: 68ch; font-size: 17px; line-height: 1.72; }
.post-content p { margin: 0 0 20px; }
.post-content h2 {
  margin: 36px 0 12px;
  padding-top: 16px;
  border-top: 2px solid var(--divider);
  font-size: 28px;
  counter-increment: h2;
}
/* Auto-numbered sections, mirroring the prompt/console idea. */
.post-content h2::before {
  content: "## " counter(h2, decimal-leading-zero);
  display: block;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 400;
  color: var(--accent-ink);
  letter-spacing: 0;
  margin-bottom: 6px;
}
.post-content { counter-reset: h2; }
.post-content h3 { font-size: 21px; margin: 28px 0 10px; }
.post-content ul, .post-content ol { margin: 0 0 20px; padding-left: 22px; }
.post-content li { margin-bottom: 8px; }
.post-content a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }
.post-content :not(pre) > code {
  font-family: var(--mono);
  font-size: 0.9em;
  color: var(--accent-ink);
  background: var(--surface);
  padding: 1px 6px;
}
.post-content blockquote {
  margin: 0 0 20px;
  border-left: 2px solid var(--divider);
  padding: 4px 18px;
  color: var(--muted);
}
.post-content table { width: 100%; border-collapse: collapse; margin: 0 0 20px; font-size: 15px; }
.post-content th {
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: left;
  padding: 8px 10px 8px 0;
  border-bottom: 2px solid var(--divider);
}
.post-content td { padding: 8px 10px 8px 0; border-bottom: 1px solid var(--soft); }
.post-content hr { border: 0; border-top: 1px solid var(--soft); margin: 28px 0; }

.post-toc { position: sticky; top: 24px; align-self: start; font-size: 13px; }
.post-toc .kicker { display: block; padding-bottom: 8px; border-bottom: 2px solid var(--divider); letter-spacing: 0.08em; text-transform: uppercase; }
.post-toc ol, .post-toc ul { list-style: none; margin: 0; padding: 0; }
.post-toc li a {
  display: flex;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--soft);
  color: var(--muted);
}
.post-toc li a:hover { color: var(--accent-ink); }
.post-toc .num { font-family: var(--mono); font-size: 11px; }
.post-share { margin-top: 24px; }
.post-share .kicker { display: block; padding-bottom: 8px; border-bottom: 2px solid var(--divider); letter-spacing: 0.08em; }
.post-share .links { display: flex; gap: 12px; flex-wrap: wrap; font-family: var(--mono); font-size: 12px; padding-top: 10px; }

.post-nav {
  margin-top: 48px;
  border-top: 2px solid var(--divider);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--soft);
}
.post-nav > * { background: var(--bg); padding: 18px 18px 18px 0; }
.post-nav .next { text-align: right; padding: 18px 0 18px 18px; }
.post-nav .kicker { display: block; margin-bottom: 6px; }
.post-nav .t { font-size: 15px; font-weight: 600; line-height: 1.3; }
.post-nav a:hover .t { color: var(--accent-ink); }

@media (max-width: 1000px) {
  .post-layout.has-toc { grid-template-columns: 1fr; }
  .post-toc { display: none; }
  .series-strip { grid-template-columns: 1fr; }
  .series-label { border-right: 0; border-bottom: 1px solid var(--soft); padding: 14px 0; min-width: 0; }
}
@media (max-width: 720px) {
  .post-head h1 { font-size: 30px; }
  .post-nav { grid-template-columns: 1fr; }
  .post-nav .next { text-align: left; padding: 18px 18px 18px 0; }
}

/* --- code blocks ---------------------------------------------------------
   The priority element: most posts are a few paragraphs wrapped around a large
   T-SQL block. Always a dark terminal, in both themes.
   ------------------------------------------------------------------------- */
.codeblock {
  margin: 24px 0;
  background: var(--code-bg);
  border: 1px solid var(--soft);
  color: var(--code-text);
}
.codeblock-head {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--code-rule);
  font-family: var(--mono);
  font-size: 12px;
}
.codeblock-lang { color: var(--code-kw); font-weight: 600; }
.codeblock-file { color: var(--code-cm); margin-right: auto; }
.codeblock-btn {
  font-family: var(--mono);
  font-size: 12px;
  border: 1px solid var(--code-rule);
  background: transparent;
  color: var(--code-text);
  padding: 4px 10px;
  cursor: pointer;
}
.codeblock-btn:hover { background: rgba(232, 234, 240, 0.08); }
.codeblock-btn.is-primary { background: var(--code-kw); color: #0f1117; border-color: var(--code-kw); font-weight: 600; }

.codeblock-body { position: relative; }
.codeblock pre {
  margin: 0;
  padding: 14px 0 14px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 13.5px;
  line-height: 1.6;
  tab-size: 2;
  font-variant-ligatures: none;
  background: transparent !important;
}
.codeblock pre code { background: transparent; padding: 0; border: 0; color: inherit; }

/* Line numbers via a counter, so no markup changes and copy still yields
   clean code - the gutter is generated content and is not selectable. */
.codeblock .cl { counter-increment: ln; display: block; }
.codeblock code { counter-reset: ln; }
.codeblock.has-lines .cl::before {
  content: counter(ln);
  display: inline-block;
  width: 34px;
  padding-right: 12px;
  text-align: right;
  color: var(--code-cm);
  user-select: none;
  -webkit-user-select: none;
}

/* Collapsed by default over 30 lines. */
.codeblock.is-collapsed .codeblock-body {
  max-height: 260px;
  overflow: hidden;
}
.codeblock.is-collapsed .codeblock-body::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 64px;
  background: linear-gradient(transparent, var(--code-bg));
  pointer-events: none;
}
.codeblock-foot {
  display: block;
  width: 100%;
  text-align: left;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--code-kw);
  background: transparent;
  border: 0;
  border-top: 1px solid var(--code-rule);
  padding: 10px 14px;
  cursor: pointer;
}
.codeblock-foot:hover { background: rgba(232, 234, 240, 0.06); }

/* Scroll affordance on wide queries. */
.codeblock-body.is-scrollable::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0; right: 0;
  width: 28px;
  background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.45));
  pointer-events: none;
  z-index: 1;
}

/* Fallback for any block the enhancer did not wrap (no-JS, or a stray <pre>). */
.post-content > pre,
.post-content .highlight > pre {
  background: var(--code-bg);
  border: 1px solid var(--soft);
  color: var(--code-text);
  padding: 14px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 13.5px;
  line-height: 1.6;
}

/* --- archive -------------------------------------------------------------
   The current archive is 67 undifferentiated cards. This makes it scannable:
   date / title / category / read time as columns, with filters beside them.
   ------------------------------------------------------------------------- */
.archive-head { padding: 44px var(--gutter) 0; }
.archive-head h1 { margin: 18px 0 0; font-size: 48px; letter-spacing: -0.025em; }

.blog-search {
  margin: 24px var(--gutter) 0;
  display: flex;
  align-items: stretch;
  border: 1px solid var(--divider);
  background: var(--surface);
}
.blog-search .caret { padding: 12px 0 12px 14px; font-family: var(--mono); font-size: 14px; color: var(--accent-ink); }
.blog-search .hint {
  display: flex;
  align-items: center;
  padding: 0 14px;
  border-left: 1px solid var(--soft);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}
.blog-search input, .blog-search .pf-mount { flex: 1; }
.blog-search input {
  border: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--mono);
  font-size: 14px;
  padding: 12px;
  width: 100%;
}
.blog-search input:focus { outline: none; }

.archive-layout { display: grid; grid-template-columns: 260px 1fr; gap: 40px; padding: 32px var(--gutter) 48px; }

.filter-group { margin-bottom: 28px; }
.filter-group > .kicker { display: block; padding-bottom: 8px; border-bottom: 2px solid var(--divider); }
.filter-list { list-style: none; margin: 0; padding: 0; font-size: 14px; }
.filter-list li > * {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 9px 0;
  border: 0;
  border-bottom: 1px solid var(--soft);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.filter-list .count { font-family: var(--mono); font-size: 12px; color: var(--muted); font-weight: 400; }
.filter-list [aria-pressed="true"] { color: var(--accent-ink); font-weight: 800; }
.filter-toggle { display: flex; align-items: center; gap: 10px; padding: 9px 0; cursor: pointer; font-size: 14px; }
.filter-box { width: 10px; height: 10px; border: 1px solid var(--divider); flex: none; }
.filter-toggle input { position: absolute; opacity: 0; }
.filter-toggle input:checked + .filter-box { background: var(--accent); border-color: var(--accent); }

.rows-head, .post-row {
  display: grid;
  grid-template-columns: 24px 100px 1fr 150px 60px;
  gap: 16px;
  align-items: start;
}
.rows-head {
  padding-bottom: 10px;
  border-bottom: 2px solid var(--divider);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.06em;
}
.post-row { padding: 14px 0; border-bottom: 1px solid var(--soft); }
.post-row:hover { background: var(--surface); }
/* Kept in flow when not featured so the columns stay aligned. */
.row-pin { width: 8px; height: 8px; background: var(--accent); margin-top: 7px; }
.row-pin.is-hidden { visibility: hidden; }
.row-date, .row-read, .row-cat { font-family: var(--mono); font-size: 12px; }
.row-date { color: var(--muted); }
.row-read { color: var(--muted); text-align: right; }
.row-cat { color: var(--accent-ink); }
.row-title { font-size: 16px; font-weight: 600; line-height: 1.3; }
.row-excerpt { font-size: 13px; line-height: 1.45; color: var(--muted); margin-top: 4px; }

.blog-pagination { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding-top: 18px; flex-wrap: wrap; }
.blog-listing-count { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.blog-page-list { display: flex; gap: 1px; background: var(--soft); list-style: none; margin: 0; padding: 0; }
.blog-page-pill, .blog-page-button {
  background: var(--bg);
  border: 0;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  padding: 8px 14px;
  cursor: pointer;
}
.blog-page-pill[aria-current="true"] { background: var(--accent); color: var(--on-accent); font-weight: 800; }
.blog-page-button:hover, .blog-page-pill:hover { background: var(--surface); }

@media (max-width: 1080px) {
  .archive-layout { grid-template-columns: 1fr; gap: 24px; }
  .rows-head { display: none; }
  .post-row { grid-template-columns: 16px 1fr; }
  .row-date, .row-cat, .row-read { display: none; }
  .archive-head h1 { font-size: 34px; }
}

/* --- about / generic pages ----------------------------------------------- */
.page-head { padding: 48px var(--gutter) 0; }
.page-head h1 { margin: 18px 0 0; font-size: 44px; letter-spacing: -0.025em; max-width: 20ch; }
.about-hero { display: grid; grid-template-columns: 1fr 360px; border-bottom: 2px solid var(--divider); }
.about-intro { padding: 48px var(--gutter); }
.about-intro .lede { font-size: 17px; line-height: 1.65; margin: 16px 0 0; }
.about-intro .muted { color: var(--muted); margin-top: 14px; }
.about-actions { display: flex; gap: 10px; margin-top: 24px; flex-wrap: wrap; }
.about-figure { margin: 0; border-left: 1px solid var(--soft); display: flex; flex-direction: column; }
.about-figure img { width: 100%; min-height: 380px; object-fit: cover; filter: grayscale(1) contrast(1.08); }
.about-figure figcaption {
  border-top: 1px solid var(--soft);
  padding: 12px 20px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
}
.about-section { padding: 36px var(--gutter) 0; }
.about-section:last-of-type { padding-bottom: 48px; }
.about-section > .kicker { display: block; margin-bottom: 14px; }
.skill-grid { grid-template-columns: repeat(3, 1fr); }
.skill-cell { padding: 20px; min-height: 130px; }
.skill-cell .key { font-family: var(--mono); font-size: 11px; color: var(--accent-ink); display: block; margin-bottom: 8px; }
.skill-cell h3 { font-size: 17px; margin-bottom: 6px; }
.skill-cell p { font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.cert-year { font-family: var(--mono); font-size: 11px; color: var(--muted); letter-spacing: .06em; }
.cert-name { font-weight: 800; font-size: 18px; line-height: 1.25; margin: 2px 0; }
.cert-issuer { font-family: var(--mono); font-size: 12px; color: var(--accent-ink); }
.cert-link { font-size: 13px; font-weight: 600; color: var(--accent-ink); margin-top: 8px; }

@media (max-width: 1000px) {
  .about-hero { grid-template-columns: 1fr; }
  .about-figure { border-left: 0; border-top: 1px solid var(--soft); }
  .skill-grid { grid-template-columns: 1fr; }
}

/* --- 404 ----------------------------------------------------------------- */
.nf-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; padding: 56px var(--gutter); }
.nf-panel {
  background: var(--code-bg);
  border: 1px solid var(--soft);
  padding: 20px 24px;
  font-family: var(--mono);
  font-size: 14px;
  line-height: 1.7;
  color: var(--code-text);
  margin: 18px 0 0;
}
.nf-panel .msg { color: var(--code-str); }
.nf-panel .obj { color: var(--code-id); }
.nf-panel .cm { color: var(--code-cm); }
.nf-layout h1 { font-size: 48px; margin: 28px 0 0; letter-spacing: -0.025em; }
.nf-layout .lede { font-size: 17px; color: var(--muted); margin-top: 14px; max-width: 46ch; }
.nf-side > .kicker { display: block; padding-bottom: 8px; border-bottom: 2px solid var(--divider); }
.nf-row { display: grid; grid-template-columns: 1fr auto; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--soft); align-items: baseline; }
.nf-row .t { font-size: 16px; font-weight: 600; line-height: 1.3; }
.nf-row .c { font-family: var(--mono); font-size: 12px; color: var(--accent-ink); }
.nf-actions { display: flex; gap: 10px; margin-top: 24px; flex-wrap: wrap; }

@media (max-width: 860px) {
  .nf-layout { grid-template-columns: 1fr; gap: 32px; }
  .nf-layout h1 { font-size: 34px; }
}

/* --- comments (console treatment) ---------------------------------------- */
.comments { margin: 48px var(--gutter) 0; padding-top: 16px; border-top: 2px solid var(--divider); }
.comments-header { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 8px; }
.comments-header h2 { font-size: 24px; }
.comments-note { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.comment-list, .comment-replies { list-style: none; margin: 0; padding: 0; }
.comment > article { display: grid; grid-template-columns: 36px 1fr; gap: 14px; padding: 18px 0; border-bottom: 1px solid var(--soft); }
.comment-avatar {
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface);
  font-family: var(--mono); font-size: 13px; font-weight: 600;
}
.comment-avatar.is-author { background: var(--accent); color: var(--on-accent); }
.comment-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.comment-author { font-weight: 800; font-size: 14px; }
.comment-badge {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  background: var(--accent); color: var(--on-accent); padding: 2px 6px; text-transform: uppercase;
}
.comment-head time { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.comment-body { font-size: 15px; line-height: 1.55; }
.comment-body p { margin: 0 0 10px; }
.comment-body p:last-child { margin-bottom: 0; }
.comment-body a { color: var(--accent-ink); text-decoration: underline; overflow-wrap: anywhere; }
.comment-replies { padding-left: 20px; border-left: 2px solid var(--soft); }
.comment-replies--flat { padding-left: 0; }

.comment-form-wrap { margin-top: 28px; }
.comment-form-title { font-family: var(--mono); font-size: 11px; font-weight: 400; color: var(--muted); letter-spacing: 0.07em; text-transform: lowercase; margin-bottom: 10px; }
.comment-form-note { font-size: 13px; color: var(--muted); margin-bottom: 12px; max-width: 60ch; }
.comment-form label > span { display: block; margin-bottom: 4px; font-family: var(--mono); font-size: 11px; color: var(--muted); }
.comment-form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 12px; margin-bottom: 12px; }
.comment-form input, .comment-form textarea {
  width: 100%;
  border: 1px solid var(--divider);
  background: var(--surface);
  color: var(--text);
  padding: 12px 14px;
  font: inherit;
  font-size: 14px;
}
.comment-form textarea { min-height: 96px; resize: vertical; line-height: 1.55; }
.comment-form-body { margin-bottom: 12px; }
.comment-form-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.comment-form-status { font-family: var(--mono); font-size: 12px; color: var(--muted); margin: 0; }
.comment-form-status.is-ok { color: var(--accent-ink); }
.comment-form-status.is-error { color: #f87171; }
.comment-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

@media (max-width: 720px) {
  :root { --gutter: 20px; }
  .comment-replies { padding-left: 12px; }
}

/* --- archive row fixes --------------------------------------------------- */
.post-rows { list-style: none; margin: 0; padding: 0; }
.post-rows > li { margin: 0; }

/* Title and excerpt are spans inside a grid cell, so they must be told to
   stack - otherwise the excerpt runs on from the title as one sentence. */
.row-title, .row-excerpt { display: block; }

/* Year cells double as filter buttons on the archive. */
button.year-cell {
  border: 0;
  font: inherit;
  color: var(--text);
  text-align: left;
  cursor: pointer;
  display: block;
  width: 100%;
}
button.year-cell .y { color: var(--text); }
button.year-cell[aria-pressed="true"] { background: var(--accent); }
button.year-cell[aria-pressed="true"] .y,
button.year-cell[aria-pressed="true"] .n { color: var(--on-accent); }

/* Category filter buttons sit inside .filter-list li. */
.category-chip { width: 100%; }

/* Pagefind ships its own UI with a light, rounded, icon-prefixed input that
   looks pasted into a flat dark console bar. Its documented customisation
   path is a set of CSS variables, so drive those first and only override
   chrome the variables do not reach. */
.blog-search {
  --pagefind-ui-scale: 0.75;
  --pagefind-ui-primary: var(--accent-ink);
  --pagefind-ui-text: var(--text);
  --pagefind-ui-background: transparent;
  --pagefind-ui-border: transparent;
  --pagefind-ui-border-width: 0px;
  --pagefind-ui-border-radius: 0;
  --pagefind-ui-font: var(--mono);
  position: relative;
}

.blog-search [data-pagefind-root] { flex: 1; min-width: 0; }
.blog-search .pagefind-ui,
.blog-search .pagefind-ui__form { width: 100%; margin: 0; }

.blog-search .pagefind-ui__search-input {
  width: 100%;
  box-sizing: border-box;
  border: 0;
  border-radius: 0;
  background: transparent;
  background-image: none;      /* drop the built-in magnifier */
  color: var(--text);
  font-family: var(--mono);
  font-size: 14px;
  font-weight: 400;
  padding: 13px 12px;
  height: auto;
}
.blog-search .pagefind-ui__search-input::placeholder { color: var(--muted); opacity: 1; }
.blog-search .pagefind-ui__search-input:focus { outline: none; box-shadow: none; }

.blog-search .pagefind-ui__search-clear {
  background: transparent;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 12px;
  padding: 0 12px;
}
.blog-search .pagefind-ui__search-clear:hover { color: var(--accent-ink); }

/* Results drawer: float it under the bar rather than pushing the page down. */
.blog-search .pagefind-ui__drawer {
  position: absolute;
  top: 100%;
  left: -1px;
  right: -1px;
  z-index: 20;
  max-height: 70vh;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--divider);
  border-top: 0;
  padding: 0;
}
.blog-search .pagefind-ui__result {
  border-bottom: 1px solid var(--soft);
  padding: 14px 16px;
  margin: 0;
}
.blog-search .pagefind-ui__result-title { font-size: 16px; font-weight: 600; }
.blog-search .pagefind-ui__result-link { color: var(--text); }
.blog-search .pagefind-ui__result-link:hover { color: var(--accent-ink); }
.blog-search .pagefind-ui__result-excerpt { font-size: 13px; color: var(--muted); }
.blog-search .pagefind-ui__message {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
  padding: 12px 16px;
  margin: 0;
}

/* --- experience / resume -------------------------------------------------
   Career history as a console table. The synthetic certification "badges"
   that used to head this page were generated gradient rectangles - rounded,
   blue and green, in a zero-radius system whose blue and green are reserved
   for code. The real proof is the credential link, so that is what shows.
   ------------------------------------------------------------------------- */
.timeline { border-top: 2px solid var(--divider); }

.tl-row {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 24px;
  padding: 20px 0;
  border-bottom: 1px solid var(--soft);
}
.tl-period {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
  padding-top: 4px;
}
.tl-role { font-size: 19px; line-height: 1.25; }
.tl-org {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--accent-ink);
  margin-top: 4px;
}
.tl-summary { font-size: 14.5px; line-height: 1.6; color: var(--muted); margin-top: 8px; max-width: 70ch; }

.tl-row--compact { padding: 12px 0; }
.tl-row--compact .tl-role { font-size: 15px; font-weight: 600; }

.tl-earlier > summary {
  list-style: none;
  cursor: pointer;
  padding: 14px 0;
  border-bottom: 1px solid var(--soft);
}
.tl-earlier > summary::-webkit-details-marker { display: none; }
.tl-earlier > summary:hover .kicker { color: var(--accent-ink); }
.tl-earlier[open] > summary .kicker::first-letter { visibility: hidden; }

/* Real issuer artwork, kept small. These are colourful by nature and the
   palette reserves saturation for code, so they sit at 56px rather than
   competing with the page. */

.cert-note { display: block; font-size: 13px; color: var(--muted); margin-top: 3px; font-weight: 400; }

.skill-grid--two { grid-template-columns: repeat(2, 1fr); }
.skill-items { margin: 8px 0 0; padding-left: 18px; }
.skill-items li { font-size: 13.5px; line-height: 1.55; color: var(--muted); margin-bottom: 6px; }

.plain-list { list-style: none; margin: 0; padding: 0; border-top: 2px solid var(--divider); }
.plain-list li {
  padding: 12px 0;
  border-bottom: 1px solid var(--soft);
  font-size: 14px;
  color: var(--muted);
}

/* The highlights strip carries no body copy, so the cells need less height. */
.status-strip .status-cell .status-value:only-of-type { margin-bottom: 0; }

@media (max-width: 860px) {
  .tl-row { grid-template-columns: 1fr; gap: 6px; }
  .skill-grid--two { grid-template-columns: 1fr; }
}

/* Certifications as cells rather than table rows. The badge is the point -
   it gets real size - and a cell without artwork simply reads as a text
   cell instead of leaving an obvious hole in a table column. */
.cert-grid { grid-template-columns: repeat(3, 1fr); }
.cert-cell {
  padding: 24px 20px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}
/* Mixed artwork: the two issuer cards are 360x200 landscape, the DAMA badge
   is square. A fixed height with auto width lines them up on a common
   baseline instead of letterboxing the wide ones into a square slot. */
.cert-art {
  height: 110px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
}
.cert-copy { display: flex; flex-direction: column; gap: 4px; }

@media (max-width: 1000px) {
  .cert-grid { grid-template-columns: 1fr; }
  .cert-cell { flex-direction: row; align-items: center; gap: 20px; }
  .cert-art { width: 88px; height: 88px; flex: none; }
}

/* --- about page certification rows ---------------------------------------
   The about page lists certifications compactly (no artwork), unlike the
   Experience page which uses the badge cell grid. These row styles were
   removed with the old grid and need to exist on their own.
   ------------------------------------------------------------------------- */
.about-section .cert-row {
  display: grid;
  grid-template-columns: 70px 1fr 220px 96px;
  gap: 20px;
  align-items: baseline;
  padding: 14px 0;
  border-bottom: 1px solid var(--soft);
}
.about-section .cert-row:first-of-type { border-top: 2px solid var(--divider); }
.about-section .cert-row .cert-name { font-size: 17px; }

/* .Content renders multiple paragraphs into the lede; they need separating. */
.about-intro .lede p { margin: 0 0 14px; }
.about-intro .lede p:last-child { margin-bottom: 0; }

@media (max-width: 860px) {
  .about-section .cert-row { grid-template-columns: 60px 1fr; }
  .about-section .cert-row .cert-issuer,
  .about-section .cert-row .cert-link { display: none; }
}

/* Pagefind's stylesheet is injected at runtime, so it loads after this file
   and wins any tie on specificity. Its rules are two classes deep
   (.pagefind-ui__form.svelte-xxxx:before), so these repeat the class to get a
   third and win outright - preferable to !important, which would be harder to
   override later. */
.blog-search .pagefind-ui__form.pagefind-ui__form::before {
  display: none;
  content: none;
}

.blog-search .pagefind-ui__search-input.pagefind-ui__search-input {
  width: 100%;
  box-sizing: border-box;
  height: auto;
  /* their padding reserves 54px for the icon that is now hidden */
  padding: 13px 12px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--mono);
  font-size: 14px;
  font-weight: 400;
}
.blog-search .pagefind-ui__search-input.pagefind-ui__search-input::placeholder {
  color: var(--muted);
  opacity: 1;
}
.blog-search .pagefind-ui__search-clear.pagefind-ui__search-clear {
  background: transparent;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 12px;
  padding: 0 12px;
  height: auto;
}

/* --- mobile -------------------------------------------------------------
   Playwright found every page scrolling sideways at 390px. Two causes: the
   header nav never collapsed, and 68ch is wider than a phone.
   ------------------------------------------------------------------------- */

/* A ch-based measure is right for reading and wrong for narrow screens;
   min() keeps the measure without ever exceeding the column. */
.post-content { max-width: min(68ch, 100%); }
.post-content pre,
.post-content table,
.codeblock { max-width: 100%; }

/* Long unbroken strings (error messages, paths, URLs) must not push the page. */
.post-content p,
.post-content li,
.row-title,
.row-excerpt,
.result-title,
.post-head h1,
.comment-body { overflow-wrap: break-word; }

@media (max-width: 860px) {
  /* Collapse the nav behind the existing toggle, which baseof.html already
     wires to data-nav-open on the header. */
  .nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    background: transparent;
    border: 1px solid var(--divider);
    color: var(--text);
    font-family: var(--mono);
    font-size: 12px;
    padding: 6px 10px;
    cursor: pointer;
  }
  .site-header .header-row { flex-wrap: wrap; gap: 12px; }
  .brand { margin-right: 0; }

  .site-nav {
    display: none;
    width: 100%;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    border-top: 1px solid var(--soft);
    padding-top: 8px;
  }
  .site-header[data-nav-open="true"] .site-nav { display: flex; }
  .site-nav a {
    width: 100%;
    padding: 11px 0;
    border-bottom: 1px solid var(--soft);
  }
  #theme-toggle { margin-top: 10px; }
}

@media (max-width: 480px) {
  .home-intro h1 { font-size: 24px; }
  .post-head h1 { font-size: 26px; }
  .hero-query-sql { font-size: 14px; }
  .hero-query { margin-left: var(--gutter); margin-right: var(--gutter); }
  .result-head, .result-row { grid-template-columns: 30px 1fr; }
  .result-date, .result-cat { display: none; }
  .codeblock pre { font-size: 12px; }
}

/* A `1fr` grid track defaults to min-width:auto, so it grows to fit its widest
   child rather than letting that child scroll. That is why a wide code block
   stretched the whole post column past the viewport instead of scrolling
   inside its own container. minmax(0, 1fr) lets the track shrink. */
.post-layout { grid-template-columns: minmax(0, 1fr); }
.post-layout.has-toc { grid-template-columns: minmax(0, 1fr) 260px; }
.home-main { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.archive-layout { grid-template-columns: 260px minmax(0, 1fr); }
.cellgrid { min-width: 0; }
.cellgrid > * { min-width: 0; }

@media (max-width: 1000px) {
  .post-layout.has-toc { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 1080px) {
  .home-main { grid-template-columns: minmax(0, 1fr); }
  .archive-layout { grid-template-columns: minmax(0, 1fr); }
}
