/* Deque Lab — shared styles */
:root {
  /* Tweakable accent (overridden by Tweaks) */
  --accent: #4f8c3a;
  --accent-ink: #ffffff;
  --accent-soft: color-mix(in oklch, var(--accent) 12%, white);
  --accent-mid: color-mix(in oklch, var(--accent) 70%, black);

  /* Surfaces */
  --ink: #0e1210;
  --ink-2: #1a201c;
  --ink-3: #2a302c;
  --paper: #fbfaf7;
  --paper-2: #f4f2ec;
  --paper-3: #ecebe3;
  --line: #e6e3d9;
  --line-2: #d8d4c6;
  --muted: #6b6f68;
  --muted-2: #8a8d85;

  /* Type */
  /* Lato is the site face everywhere — headings, prose, nav, cards, tables.
     It ships 100/300/400/700/900 and no 500 or 600, so the weights used across
     the design round to 400 and 700; the scale is built around that, not
     against it. Geist Mono stays for eyebrows, counters and badges. */
  --f-sans: 'Lato', ui-sans-serif, system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;
  --f-mono: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Rhythm */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 18px;
  --pad: clamp(20px, 4vw, 56px);
  --max: 1320px;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--f-sans);
  color: var(--ink);
  background: var(--paper);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
button { font-family: inherit; cursor: pointer; }

.flex {
  display: flex;
  gap: 10px;
}

.mt-3 {
  margin-top: 1rem;
}

.mono { font-family: var(--f-mono); font-feature-settings: "ss01"; }
.eyebrow {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.eyebrow::before {
  content: "";
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  display: inline-block;
}
.eyebrow.on-dark { color: var(--muted); }

/* Layout */
.wrap {
  max-width: var(--max);
  margin: 0 auto;
  padding-left: var(--pad);
  padding-right: var(--pad);
}
.grid { display: grid; gap: 24px; }

/* Nav (white) */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: #fff;
  border-bottom: 1px solid var(--line);
}
/* Logo left · links centered · Contact right */
.nav-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: 68px;
}
.nav-inner .brand { justify-self: start; }
.nav-inner .nav-links { justify-self: center; }
.nav-inner .nav-actions { justify-self: end; }
.brand {
  display: inline-flex; align-items: center; gap: 12px;
  font-weight: 600; letter-spacing: -0.01em;
}
.brand-mark {
  height: 32px;
  display: inline-flex; align-items: center;
  overflow: hidden;
}
.brand-mark svg { height: 32px; width: auto; }
.brand-mark img { height: 32px; width: auto; display: block; }
.site-footer .brand-mark { height: 40px; }
.site-footer .brand-mark img { height: 40px; }

.nav-links {
  display: flex; align-items: center; gap: 4px;
}
.nav-links a {
  padding: 8px 12px;
  font-size: 14px;
  border-radius: 8px;
  transition: color 120ms ease, background 120ms ease;
}
.nav-links a:hover { color: var(--ink); background: var(--paper-2); }
.nav-links a.active { color: var(--ink); }
.nav-actions {
  display: flex; align-items: center; gap: 4px;
}
.nav-actions a:not(.btn) {
  padding: 8px 12px;
  font-size: 14px;
  border-radius: 8px;
  transition: color 120ms ease, background 120ms ease;
}
.nav-actions a:not(.btn):hover { color: var(--ink); background: var(--paper-2); }
.nav-cta {
  margin-left: 8px;
}
@media (max-width: 820px) {
  .nav-links a:not(.nav-cta) { display: none; }
  .nav-actions a:not(.btn) { display: none; }
  .nav-cta { margin-left: 0; }
}

/* Buttons */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  height: 44px; padding: 0 20px;
  border-radius: 999px;
  font-size: 14px; font-weight: 500;
  border: 1px solid transparent;
  transition: transform 120ms ease, background 120ms ease, color 120ms ease, border-color 120ms ease;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn-primary { background: var(--ink); color: var(--paper); }
.btn-primary:hover { background: var(--accent); color: var(--accent-ink); }
.btn-outline { background: transparent; color: var(--ink); border-color: var(--line-2); }
.btn-outline:hover { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn-accent { background: var(--accent); color: var(--accent-ink); }
.btn-accent:hover { background: var(--accent-mid); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--line-2); }
.btn-ghost:hover { border-color: var(--ink); }
.btn-ghost.on-dark { color: var(--paper); border-color: rgba(255,255,255,0.2); }
.btn-ghost.on-dark:hover { border-color: var(--paper); }
.btn-arrow::after {
  content: "→"; font-family: var(--f-mono);
}
.btn-sm { height: 36px; padding: 0 14px; font-size: 13px; }

/* Section */
section { padding: clamp(64px, 9vw, 120px) 0; }
.section-head {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: 40px;
  align-items: end;
  margin-bottom: 56px;
}
@media (max-width: 820px) {
  .section-head { grid-template-columns: 1fr; }
}
h1, h2, h3, h4 { font-weight: 500; letter-spacing: -0.02em; margin: 0; }
h1 { font-size: clamp(44px, 6.8vw, 96px); line-height: 0.98; letter-spacing: -0.035em; }
h2 { font-size: clamp(30px, 4vw, 52px); line-height: 1.05; letter-spacing: -0.025em; }
h3 { font-size: clamp(20px, 1.8vw, 26px); line-height: 1.2; letter-spacing: -0.015em; }
h4 { font-size: 16px; }
p { margin: 0; }
.lede { font-size: clamp(17px, 1.4vw, 20px); color: var(--muted); line-height: 1.55; max-width: 56ch; }

/* Card */
.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 28px;
  transition: border-color 150ms ease, transform 150ms ease;
}
.card:hover { border-color: var(--ink); }

/* Footer (white) */
footer.site-footer {
  background: #fff; color: var(--ink);
  border-top: 1px solid var(--line);
  padding: 64px 0 32px;
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 40px;
  padding-bottom: 40px;
  border-bottom: 1px solid var(--line);
}
@media (max-width: 820px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
}
/* An <h2>, not the <h5> this used to be: the footer sits under the page's
   <h1> with nothing between, so h5 skipped three levels. font-weight and
   line-height are pinned because h2 picks up the display scale at line 188
   and h5 did not — without them the labels would render lighter and tighter. */
.footer-col h2 {
  font-family: var(--f-mono);
  font-size: 11px; font-weight: 700; line-height: 1.5;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 20px;
}
.footer-col ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.footer-col a { color: var(--muted); font-size: 14px; transition: color 120ms ease; }
.footer-col a:hover { color: var(--accent); }
.footer-socials { display: flex; gap: 12px; margin-top: 20px; }
.footer-socials a {
  width: 40px; height: 40px; border-radius: 11px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--paper-2); border: 1px solid var(--line);
  transition: border-color 150ms ease, transform 150ms ease;
}
.footer-socials a:hover { border-color: var(--accent); transform: translateY(-1px); }
.footer-socials img { width: 20px; height: 20px; display: block; }

.footer-meta {
  display: flex; justify-content: space-between; padding-top: 24px;
  font-size: 12px; color: var(--muted); font-family: var(--f-mono);
  gap: 16px; flex-wrap: wrap;
}
.footer-legal { display: inline-flex; align-items: center; gap: 10px; }
.footer-legal a { color: var(--muted); transition: color 120ms ease; }
.footer-legal a:hover { color: var(--accent); }
.footer-legal span[aria-hidden] { color: var(--line-2); }

/* Utility */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--f-mono);
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 5px 10px;
  border-radius: 999px;
  background: var(--paper-2);
  color: var(--muted);
  border: 1px solid var(--line);
}
.badge.solid { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.badge.dark { background: var(--ink); color: var(--paper); border-color: transparent; }
.badge.sold { background: #fff4e5; color: #a45300; border-color: #f4d9b0; }

.placeholder {
  background:
    repeating-linear-gradient(135deg, var(--paper-2) 0 10px, var(--paper-3) 10px 20px);
  border: 1px dashed var(--line-2);
  color: var(--muted);
  font-family: var(--f-mono);
  font-size: 11px;
  display: grid; place-items: center;
  border-radius: 12px;
  text-align: center;
  padding: 16px;
}
.placeholder.dark {
  background:
    repeating-linear-gradient(135deg, #181d1a 0 10px, #1f2522 10px 20px);
  border-color: #2a302c;
  color: #6b6f68;
}

/* Hairline */
.hair { height: 1px; background: var(--line); border: 0; margin: 0; }
.hair.dark { background: var(--ink-3); }

/* Mock UI primitives */
.mock {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  font-size: 13px;
}
.mock-bar {
  display: flex; align-items: center; gap: 6px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--paper-2);
}
.mock-bar .dot { width: 10px; height: 10px; border-radius: 50%; background: #d8d4c6; }
.mock-bar .url {
  margin-left: 10px; font-family: var(--f-mono); font-size: 11px; color: var(--muted);
}

/* ============================================================
 * Shared page chrome + contact form (used by index & subpages)
 * ============================================================ */

/* Accessibility: skip link */
.skip-link {
  position: absolute; top: -40px; left: 8px;
  background: var(--ink); color: var(--paper);
  padding: 10px 14px; border-radius: 8px; z-index: 999;
  font-family: var(--f-mono); font-size: 12px;
  transition: top 150ms ease;
}
.skip-link:focus { top: 8px; outline: 2px solid var(--accent); outline-offset: 2px; }

/* visually-hidden for accessibility (screen-reader-only labels) */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

html { scroll-behavior: smooth; scroll-padding-top: 80px; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ============ Contact (light) ============ */
.contact-wrap {
  background: #fff; color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 28px;
  display: grid; grid-template-columns: 1fr 1.1fr; gap: 56px;
  position: relative; overflow: hidden;
}
@media (max-width: 820px) { .contact-wrap { grid-template-columns: 1fr; gap: 40px; } }
.contact-wrap::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(800px 500px at 110% 0%, color-mix(in oklch, var(--accent) 8%, transparent), transparent 60%);
  pointer-events: none;
}
.contact-wrap > * { position: relative; }

.contact-wrap h2 {
  font-size: clamp(32px, 4.4vw, 56px); letter-spacing: -0.03em; line-height: 1.02; font-weight: 500;
}
.contact-wrap h2 em { font-style: normal; color: var(--accent); }
.contact-wrap .lede { color: var(--muted); max-width: 42ch; }

/* Friendly "talk to a human" founder block */
.contact-wrap .talk { margin-top: 32px; }
.contact-wrap .talk-title {
  font-size: clamp(22px, 2.4vw, 30px); font-weight: 500; letter-spacing: -0.02em; line-height: 1.1;
  color: var(--ink);
}
.contact-wrap .talk-title em { font-style: italic; color: var(--accent); }
.contact-wrap .talk-sub { color: var(--muted); font-size: 15px; line-height: 1.55; margin-top: 12px; max-width: 42ch; }
.contact-wrap .person {
  display: flex; align-items: center; gap: 22px; margin-top: 24px;
}
.contact-wrap .person-avatar {
  width: 112px; height: 112px; flex: none; border-radius: 50%;
  object-fit: cover; border: 3px solid #fff;
  box-shadow: 0 8px 22px rgba(14,18,16,0.14), 0 0 0 1px var(--line);
}
.contact-wrap .person-name { font-weight: 600; font-size: 19px; color: var(--ink); letter-spacing: -0.015em; }
.contact-wrap .person-role {
  font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); margin-top: 4px;
}
.contact-wrap .person-contacts { display: flex; flex-direction: column; gap: 3px; margin-top: 12px; }
.contact-wrap .person-contacts a { font-size: 14px; color: var(--accent); width: fit-content; }
.contact-wrap .person-contacts a:hover { text-decoration: underline; }

/* Founder business-card */
.contact-wrap .founder-card {
  position: relative;
  background: var(--paper-2);
  padding: 38px 30px 32px;
  text-align: center;
  height: 100%;
}
.contact-wrap .founder-arrow {
  position: absolute; top: 16px; right: 18px;
  width: 56px; height: 52px; color: var(--accent);
  opacity: 0.9; pointer-events: none;
}
.contact-wrap .founder-arrow svg { width: 100%; height: 100%; display: block; }
.contact-wrap .founder-avatar {
  width: 150px; 
  height: 150px; 
  border-radius: 50%;
  object-fit: cover; 
  border: 4px solid #fff;
  margin-left: auto;
  margin-right: auto;
  box-shadow: 0 10px 26px rgba(14,18,16,0.16), 0 0 0 1px var(--line);
}
.contact-wrap .founder-name {
  margin-top: 18px; font-weight: 700; font-size: 22px;
  color: var(--ink); letter-spacing: -0.02em;
}
.contact-wrap .founder-role {
  margin-top: 6px; font-family: var(--f-mono);
  font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}
.contact-wrap .founder-tagline {
  margin: 5px auto 0; 
  color: var(--muted); 
  font-size: 16px; 
  line-height: 1.5;
}
.contact-wrap .founder-divider {
  display: block; 
  width: 128px; 
  height: 1px;
  margin: 15px auto; 
  background: var(--line-2);
}
.contact-wrap .founder-contacts {
  list-style: none; 
  margin: 0 auto; 
  padding: 0;
  display: flex; 
  flex-direction: column; 
  gap: 10px;
  width: fit-content; 
  text-align: left;
}
.contact-wrap .founder-contacts a {
  display: inline-flex; align-items: center; gap: 14px;
  color: var(--ink); font-size: 17px; font-weight: 500;
  transition: color 150ms ease;
}
.contact-wrap .founder-contacts a:hover { color: var(--accent); }
.contact-wrap .fc-ic {
  flex: none; width: 22px; height: 22px; color: var(--accent);
  display: inline-flex; align-items: center; justify-content: center;
}
.contact-wrap .fc-ic svg { width: 22px; height: 22px; display: block; }

.ctry { display: flex; gap: 12px; margin-top: 24px; flex-wrap: wrap; }
.ctry .chip-link {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  background: var(--paper-2); border: 1px solid var(--line);
  border-radius: 999px; color: var(--ink);
  font-size: 13px; transition: border-color 150ms ease, background 150ms ease;
}
.ctry .chip-link:hover, .ctry .chip-link:focus { border-color: var(--accent); background: #fff; }
.ctry .chip-link svg { width: 16px; height: 16px; }

/* Icon-only social/contact buttons (fixed size) */
.ctry .ico-link {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none;
  transition: border-color 150ms ease, background 150ms ease, color 150ms ease, transform 150ms ease;
}
.ctry .ico-link:hover, .ctry .ico-link:focus-visible { border-color: var(--accent); color: var(--accent); background: #fff; transform: translateY(-1px); }
.ctry .ico-link img { width: 25px; height: 25px; display: block; }

.form {
  padding: 28px;
}
.form-row { display: grid; gap: 18px; }
.form-row .f label {
  display: block; font-family: var(--f-mono); font-size: 10px;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted);
  margin-bottom: 8px;
}
.form-row .f label .req { color: var(--accent); }
.form-row input, .form-row textarea, .form-row select {
  width: 100%; padding: 13px 14px;
  border: 1px solid var(--line); background: #fff; color: var(--ink);
  border-radius: 10px; font-family: var(--f-sans); font-size: 14px;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.form-row input:focus, .form-row textarea:focus, .form-row select:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 14%, transparent);
}
.form-row input::placeholder, .form-row textarea::placeholder { color: var(--muted-2); }
.form-row textarea { min-height: 110px; resize: vertical; }
.form .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 480px) { .form .grid2 { grid-template-columns: 1fr; } }
.form .submit {
  margin-top: 20px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.form .submit .note { font-family: var(--f-mono); font-size: 11px; color: var(--muted); max-width: 30ch; line-height: 1.5; }
.form button.btn { border: 0; cursor: pointer; }
.form .hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-success {
  background: color-mix(in oklch, var(--accent) 10%, white);
  border: 1px solid color-mix(in oklch, var(--accent) 35%, white);
  border-radius: 14px; padding: 28px;
  text-align: center;
}
.form-success .tick {
  width: 52px; height: 52px; margin: 0 auto 14px;
  background: var(--accent); color: var(--accent-ink); border-radius: 50%;
  display: grid; place-items: center; font-size: 24px;
}
.form-success h4 { font-size: 20px; font-weight: 500; color: var(--ink); margin: 0 0 6px; }
.form-success p { color: var(--muted); font-size: 14px; }

.form-errors {
  background: #fff5f5; border: 1px solid #f3c5c5;
  border-radius: 10px; padding: 14px 16px; margin-bottom: 18px;
  color: #8a2c2c; font-size: 13px;
}
.form-errors ul { margin: 0; padding-left: 18px; }

/* ============================================================
   Post cards + HTML cover art
   Shared by the homepage row, /blogs and the related cards, so
   the component is defined once here rather than re-pasted into
   each page's inline <style>.
   ============================================================ */
.blog { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 860px) { .blog { grid-template-columns: 1fr; } }

.post {
  background: #fff; border: 1px solid var(--line); border-radius: 20px;
  overflow: hidden; display: flex; flex-direction: column;
  transition: border-color 200ms ease, transform 200ms ease;
}
a.post:hover { border-color: var(--ink); transform: translateY(-2px); }
a.post:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Inert by definition: a coming-soon card has nowhere to go. */
article.post { opacity: 0.82; }

.post .body { padding: 22px; display: flex; flex-direction: column; flex: 1; }
.post .meta {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--f-mono); font-size: 11px; color: var(--muted);
}
.post .meta .tg {
  padding: 3px 9px; border-radius: 999px;
  background: var(--paper-2); border: 1px solid var(--line); letter-spacing: 0.04em;
}
.post .meta .dot { color: var(--line-2); }
.post h3 { font-size: 18px; font-weight: 500; letter-spacing: -0.015em; margin-top: 12px; }
.post p { color: var(--muted); font-size: 14px; line-height: 1.55; margin-top: 10px; }
.post .rd {
  margin-top: auto; padding-top: 18px;
  font-family: var(--f-mono); font-size: 12px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--accent);
}
article.post .rd { color: var(--muted-2); }

/* ---- Cover art ----
   Drawn in HTML instead of shipped as a file: no request, sharp at any zoom,
   and a new post needs a registry entry rather than a trip to a design tool.
   Everything is sized in cqw against the card, so the same markup fills a
   3-up homepage row and a wide /blogs card without a second art direction. */
.cover-art {
  container-type: inline-size;
  position: relative; overflow: hidden;
  aspect-ratio: 3 / 2;
  /* Percent, not cqw. An element is never its own query container, so cqw here
     would resolve against the viewport instead of the card — at 1440px that
     came out as 86px of padding, which crushed the content box and left every
     child's cqw sized against 203px instead of the card. Percentage padding
     resolves against the card width, which is what was meant all along. */
  padding: 6% 6.5%;
  display: flex; flex-direction: column;
  background: var(--paper-2);
  border-bottom: 1px solid var(--line);
}
/* Accent haze, edgeless — the same device the article hero uses. */
.cover-art::after {
  content: ""; position: absolute; right: -18%; top: -34%;
  width: 62%; aspect-ratio: 1; border-radius: 50%;
  background: color-mix(in oklch, var(--accent) 14%, transparent);
}
.cover-art > * { position: relative; z-index: 1; }
.cv-eyebrow {
  font-family: var(--f-mono); font-size: 2.7cqw; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--muted);
}
.cv-title {
  font-size: 5.4cqw; 
  line-height: 1.12; 
  letter-spacing: -0.03em;
  font-weight: 700; 
  color: var(--ink);
  align-self: center; 
  flex: 1 1 auto; 
  min-width: 0;
}
.cv-title b { color: var(--accent); font-weight: 600; }
.cv-foot {
  margin-top: auto;
  font-family: var(--f-mono); font-size: 3.5cqw; color: var(--muted-2);
}

/* Title left, motif right. A flex row, so the two can never overlap however
   long the headline runs. */
.cv-main {
  flex: 1; min-height: 0;
  margin-top: 2.6cqw;
  display: flex; align-items: flex-start; gap: 4cqw;
}
.cv-card {
  align-self: flex-end;
  flex: 0 0 42cqw; padding: 3.4cqw 3.8cqw;
  background: #fff; border: 1px solid var(--line); border-radius: 3.4cqw;
  box-shadow: 0 2.2cqw 5.5cqw rgba(14, 18, 16, 0.09);
  display: grid; gap: 1.9cqw;
}
.cv-row {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 4.1cqw;
}
.cv-row i { font-style: normal; color: var(--muted); }
.cv-row b { color: var(--ink); font-weight: 600; }
.cv-row.hi b { color: var(--accent); }
.cv-field {
  height: 4.2cqw; border-radius: 1.2cqw;
  background: var(--paper-2); border: 1px solid var(--line);
}
.cv-field.short { width: 62%; }
.cv-btn {
  margin-top: 0.8cqw; padding: 1.7cqw 0; border-radius: 1.7cqw;
  background: var(--accent); color: var(--accent-ink);
  font-size: 3.6cqw; text-align: center; font-weight: 600;
}
/* Quote motif: a product card with the price taken out of it. The lock row is
   where the number used to be, so the swap the article describes is the thing
   the banner shows. */
.cv-lock {
  display: flex; align-items: center; gap: 1.6cqw;
  font-size: 3.6cqw; color: var(--muted);
}
.cv-lock svg { width: 4.2cqw; height: 4.2cqw; flex: none; color: var(--muted-2); }

.cv-line { height: 3cqw; border-radius: 1.2cqw; background: var(--paper-2); }
.cv-line.w1 { width: 90%; } .cv-line.w2 { width: 70%; } .cv-line.w3 { width: 80%; }
.cv-total {
  margin-top: 1.2cqw; padding-top: 2.2cqw; border-top: 1px dashed var(--line);
  display: flex; justify-content: space-between; align-items: baseline; font-size: 4.1cqw;
}
.cv-total i { font-style: normal; color: var(--accent); }
.cv-total b { color: var(--ink); font-weight: 600; }

/* A card with no motif lets the headline breathe instead. */
/* No motif to sit beside, so the headline takes the whole width. */
.cover-art.cv-plain .cv-title { font-size: 9.8cqw; }

@media (prefers-reduced-motion: reduce) {
  a.post:hover { transform: none; }
}

/* ============================================================
   Blog listing: toolbar (category tabs + search) and sections
   ============================================================ */
.blog-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  padding-bottom: 22px; border-bottom: 1px solid var(--line); margin-bottom: 36px;
}
/* Tabs and the field share one row by design. Below the fold of a phone that
   row cannot hold both, so the search takes the full width underneath rather
   than shrinking to a slot too small to read what you typed. */
@media (max-width: 640px) {
  .blog-toolbar { align-items: stretch; }
  .blog-search { flex: 1 1 100%; }
}
.blog-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.blog-tab {
  padding: 9px 16px; border-radius: 999px;
  border: 1px solid transparent; background: transparent;
  font-family: inherit; font-size: 14px; color: var(--muted);
  cursor: pointer; transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.blog-tab:hover { background: var(--paper-2); color: var(--ink); }
.blog-tab[aria-pressed="true"] {
  background: var(--ink); color: var(--paper); border-color: var(--ink);
}
.blog-tab .n { font-family: var(--f-mono); font-size: 11px; opacity: 0.65; margin-left: 6px; }

.blog-search { position: relative; flex: 0 1 320px; min-width: 220px; }
.blog-search input {
  width: 100%; height: 44px; padding: 0 16px 0 42px;
  border: 1px solid var(--line-2); border-radius: 999px;
  background: #fff; font-family: inherit; font-size: 14px; color: var(--ink);
  transition: border-color 140ms ease;
}
.blog-search input::placeholder { color: var(--muted-2); }
.blog-search input:focus { outline: none; border-color: var(--accent); }
.blog-search svg {
  position: absolute; left: 15px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; color: var(--muted-2); pointer-events: none;
}

.blog-section + .blog-section { margin-top: 56px; }
.blog-section h2 {
  font-size: 22px; font-weight: 500; letter-spacing: -0.02em;
  margin-bottom: 20px; display: flex; align-items: baseline; gap: 12px;
}
.blog-section h2 .n {
  font-family: var(--f-mono); font-size: 12px; color: var(--muted); letter-spacing: 0.08em;
}
/* JS hides a section whose cards all filtered out; without JS nothing hides. */
.blog-section[hidden], .post[hidden] { display: none; }
.blog-empty {
  padding: 56px 0; text-align: center; color: var(--muted); font-size: 16px;
}
.blog-empty[hidden] { display: none; }

/* ============================================================
   Cover tones
   A banner can be painted instead of left on paper. The palettes
   live here rather than in the registry so a colour change is one
   edit, and the motif card inside stays white in every tone —
   that contrast is what makes the mock read at card size.
   ============================================================ */
.cover-art.toned {
  background: var(--tone-bg);
  border-bottom-color: transparent;
}
.tone-ink  { --tone-bg: #16201b; --tone-hi: #9ed17f; }
.tone-moss { --tone-bg: #3c6b2c; --tone-hi: #d6ecc2; }
.tone-plum { --tone-bg: #6a4a86; --tone-hi: #e3cdf5; }
.tone-clay { --tone-bg: #a4552b; --tone-hi: #ffd7b3; }
.tone-slate{ --tone-bg: #1e3b4d; --tone-hi: #a9d8ec; }

/* The accent haze reads as dirt on a dark ground; a soft white bloom is the
   same device, inverted. */
.cover-art.toned::after { background: rgba(255, 255, 255, 0.09); }
/* Bracket in the corner opposite the title — the one decorative mark, kept to
   a hairline so it never competes with the headline. */
.cover-art.toned::before {
  content: ""; position: absolute; right: 4.5%; bottom: 5.5%;
  width: 24%; height: 28%;
  border-right: 0.55cqw solid rgba(255, 255, 255, 0.24);
  border-bottom: 0.55cqw solid rgba(255, 255, 255, 0.24);
  border-bottom-right-radius: 5.5cqw;
}
.cover-art.toned .cv-eyebrow { color: rgba(255, 255, 255, 0.6); }
.cover-art.toned .cv-title   { color: #fff; }
.cover-art.toned .cv-title b { color: var(--tone-hi); }
/* On a tone the footnote becomes the badge the card was missing: same string
   from the registry, a shape that survives being read at 300px wide. */
.cover-art.toned .cv-foot {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 1.3cqw;
  margin-top: 3cqw;
  padding: 1.1cqw 2.5cqw; border-radius: 999px;
  background: rgba(255, 255, 255, 0.13);
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: #fff; font-size: 2.8cqw; letter-spacing: 0.03em;
}
.cover-art.toned .cv-foot::before {
  content: "◆"; font-size: 2.2cqw; color: var(--tone-hi);
}

/* ============================================================
   Editorial post card (/blogs listing)
   Banner on top, words underneath sitting straight on the page.
   Dropping the box is the point: with a painted banner, a second
   border around it reads as a card inside a card.
   ============================================================ */
.blog-ed { gap: 40px 28px; }
@media (max-width: 860px) { .blog-ed { gap: 34px; } }

.post.post-ed {
  background: transparent; border: 0; border-radius: 0; overflow: visible;
}
a.post.post-ed:hover { transform: none; }
a.post.post-ed:focus-visible { outline: none; }
a.post.post-ed:focus-visible .cover-art { outline: 2px solid var(--accent); outline-offset: 3px; }
article.post.post-ed { opacity: 1; }

.post-ed .cover-art {
  border-radius: var(--r-lg); border-bottom: 0;
  transition: transform 220ms ease, box-shadow 220ms ease;
}
a.post-ed:hover .cover-art {
  transform: translateY(-3px);
  box-shadow: 0 14px 34px rgba(14, 18, 16, 0.16);
}
/* Nothing to click, so nothing lifts — the muted banner says "not yet" on its own. */
article.post-ed .cover-art { filter: saturate(0.75); opacity: 0.9; }

.post-ed .body { padding: 20px 2px 0; }
.post-ed h3 {
  font-size: 20px; font-weight: 700; line-height: 1.3;
  letter-spacing: -0.02em; margin: 0;
}
a.post-ed:hover h3 { color: var(--accent-mid); }
/* Three lines, then stop. Excerpts run to different lengths and a ragged grid
   of 2- and 5-line blurbs is the thing that makes a listing look unedited. */
.post-ed p {
  margin-top: 12px; font-size: 15px; line-height: 1.6; color: var(--muted);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
}
.post-ed .meta {
  margin-top: auto; padding-top: 18px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-family: var(--f-mono); font-size: 12px; color: var(--muted);
}
.post-ed .meta .sep { color: var(--line-2); }

/* ============================================================
   Newsletter hero (/blogs)
   ============================================================ */
.nl-hero { padding: 56px 0 40px; }
.nl-grid {
  display: grid; grid-template-columns: 1.06fr 1fr; gap: 60px; align-items: center;
}
@media (max-width: 940px) { .nl-grid { grid-template-columns: 1fr; gap: 44px; } }

.nl-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 16px; border-radius: 999px;
  border: 1px solid color-mix(in oklch, var(--accent) 26%, white);
  font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--accent-mid);
}
.nl-hero h1 {
  font-size: clamp(34px, 4.9vw, 60px); line-height: 1.05;
  letter-spacing: -0.035em; font-weight: 500; margin: 22px 0 0;
}
.nl-hero .lede { margin-top: 18px; max-width: 46ch; }

.nl-form { margin-top: 30px; max-width: 540px; }

/* Field and button are one control, not two sitting next to each other: the
   shell carries the border and the focus ring, the input inside it is stripped
   bare. Focus lands on the input but the ring is drawn on the shell via
   :focus-within, so tabbing to the field lights up the whole pill. */
.nl-shell {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 6px 6px 22px;
  background: #fff;
  border: 1px solid var(--line-2); border-radius: 999px;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.nl-shell:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 14%, transparent);
}
.nl-shell input[type="email"] {
  flex: 1 1 auto; min-width: 0;
  height: 46px; padding: 0;
  border: 0; background: transparent; color: var(--ink);
  font-family: inherit; font-size: 15px;
}
.nl-shell input[type="email"]::placeholder { color: var(--muted-2); }
/* The shell already shows focus; a second outline inside it reads as a bug. */
.nl-shell input[type="email"]:focus { outline: none; }
.nl-shell .btn { flex: none; height: 46px; padding: 0 24px; border: 0; }
/* Sitting on a white shell rather than the page, the lift has nothing to lift
   off — it just makes the pill look loose inside its own border. */
.nl-shell .btn:hover { transform: none; }

/* Narrow phones: the label is what has to give, not the field. Anything less
   and there is no room left to read back the address you typed. */
@media (max-width: 420px) {
  .nl-shell { padding-left: 18px; }
  .nl-shell .btn { padding: 0 18px; font-size: 13.5px; }
}

.nl-form .hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.nl-note { margin-top: 14px; font-size: 13.5px; color: var(--muted); }
.nl-note a { color: var(--accent-mid); text-decoration: underline; text-underline-offset: 2px; }

.nl-msg {
  margin-top: 20px; padding: 14px 18px; border-radius: 14px;
  font-size: 14px; display: flex; align-items: flex-start; gap: 10px; max-width: 540px;
}
.nl-msg.ok {
  background: color-mix(in oklch, var(--accent) 10%, white);
  border: 1px solid color-mix(in oklch, var(--accent) 32%, white);
  color: var(--ink-2);
}
.nl-msg.err { background: #fff5f5; border: 1px solid #f3c5c5; color: #8a2c2c; }
.nl-msg b { font-weight: 700; }

/* ---- Hero art ----
   The same trick the article hero uses: a composition made of nothing but
   boxes and radii, so it costs no request and stays sharp at any zoom. The
   pinwheel of arched corners is what keeps four rectangles from reading as a
   spreadsheet. Sized in cqw so it scales as one drawing. */
.nl-art {
  container-type: inline-size;
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
  aspect-ratio: 1 / 0.84;
}
/* Stacked under the copy, the art has less width to work with, so the rows
   size to their content instead of to a ratio — otherwise the chips in the
   third tile get cut off by a height the viewport chose. */
@media (max-width: 940px) {
  .nl-art { max-width: 520px; aspect-ratio: auto; grid-auto-rows: minmax(150px, auto); }
}
.nl-tile {
  position: relative; overflow: hidden;
  padding: 8% 9%;
  display: flex; flex-direction: column; justify-content: center; gap: 2cqw;
  min-width: 0;
}
.nl-tile .k {
  font-family: var(--f-mono); font-size: 3cqw; letter-spacing: 0.13em;
  text-transform: uppercase; opacity: 0.62;
}
.nl-tile .v { font-size: 13cqw; line-height: 1; font-weight: 700; letter-spacing: -0.04em; }
.nl-tile .v.sm { font-size: 8.4cqw; }

.nl-tile.t1 {
  border-radius: 4cqw 19cqw 19cqw 4cqw;
  background: color-mix(in oklch, var(--accent) 15%, white);
  color: var(--accent-mid);
}
/* The arched corner eats into the padding box, so each tile gives that side
   the extra room its label needs to clear the curve. */
.nl-tile.t1 { padding-right: 13%; }
.nl-tile.t2 
{ 
  border-radius: 19cqw 4cqw 4cqw 4cqw; 
  background: #16201b; 
  color: #fff; 
  padding: 11% 9% 8% 12%; 
  text-align: right;
}

.nl-tile.t2 .v 
{ 
  color: #9ed17f; 
}

/* Painted like its three neighbours rather than left as a white card: the
   chips-on-paper version borrowed the look of a form control and read as a
   piece of UI that had wandered into the picture. Same anatomy as the others
   now — mono label above, display type below — only the payload is three
   short lines instead of one big number. */
.nl-tile.t3 {
  border-radius: 4cqw 4cqw 4cqw 19cqw;
  background: var(--accent); color: #fff;
  padding: 8% 9% 9% 13%;
  justify-content: center; gap: 2.6cqw;
}
.nl-topics {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1.5cqw;
}
.nl-topics li {
  font-size: 5.4cqw; line-height: 1.16;
  font-weight: 700; letter-spacing: -0.025em;
}
/* The lead topic is the one the blog is actually about; the other two sit a
   step back so the tile still has a focal point like "01" or "Monthly". */
.nl-topics li + li { color: rgba(255, 255, 255, 0.72); font-size: 4.6cqw; }

.nl-tile.t4 { border-radius: 4cqw 4cqw 19cqw 4cqw; background: #6a4a86; color: #fff; }
.nl-tile.t4 .v { color: #e3cdf5; }

@media (prefers-reduced-motion: reduce) {
  a.post-ed:hover .cover-art { transform: none; }
}
