/*
 * HelpMeBlake.com — "Ledger" component layer
 * -------------------------------------------------------------------------
 * Ported from the YesDesk/Nisius Ledger system. Load AFTER tokens.css.
 *
 * This file replaces the per-page inline <style> blocks that used to be
 * copy-pasted across all eight HTML files. Every color here resolves to a
 * token — a value that isn't a token can't follow the theme.
 *
 * Class names are unchanged from the dark-era build on purpose. Retargeting
 * the definitions re-themes ~2,000 utility uses without editing markup.
 */

/* ── Base ───────────────────────────────────────────────────────────────── */

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  background: rgb(var(--paper));
  color: rgb(var(--ink));
  font-family: Inter, system-ui, -apple-system, sans-serif;
  font-optical-sizing: auto;
}

::selection {
  background: rgb(var(--yes) / 0.16);
  color: rgb(var(--ink));
}

::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: rgb(var(--paper-sunk)); }
::-webkit-scrollbar-thumb { background: rgb(var(--line-strong)); border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: rgb(var(--ink-3)); }

/* Every metric, price, duration and timestamp lines up. */
.tabular,
.stat-value { font-variant-numeric: tabular-nums; }

/*
 * Pre-Tailwind paint guard. tokens.css + this file are real stylesheets, so
 * they apply before the Tailwind CDN has JIT'd anything. These few rules cover
 * the utilities that would otherwise flash unstyled.
 */
.text-surface { color: rgb(var(--ink)); }
.text-muted { color: rgb(var(--ink-2)); }
.text-muted-dark { color: rgb(var(--ink-3)); }
.bg-base { background-color: rgb(var(--paper)); }
.border-transparent { border-color: transparent; }

/* ── Typography ─────────────────────────────────────────────────────────────
   One family does UI and display; the optical-size axis carries the weight a
   display face used to. Scale contrast is the signal, not glow. */

.heading-hero {
  font-size: clamp(44px, 7vw, 88px);
  line-height: 0.98;
  letter-spacing: -0.032em;
  max-width: 18ch;
  text-wrap: balance;
}

.heading-section {
  font-size: clamp(30px, 4vw, 46px);
  line-height: 1.06;
  letter-spacing: -0.022em;
  max-width: 26ch;
  text-wrap: balance;
}

/*
 * The old cyan→violet gradient hero word. There is one brand color now, so
 * it's just the brand color — kept as a class so existing call sites work.
 */
.gradient-text { color: rgb(var(--yes-line)); }

/*
 * Micro-labels stay uppercase but are no longer mono and no longer accent
 * colored. Mono UI chrome was the loudest "this is for developers" tell in
 * the old system, and it is exactly what this audience does not need.
 */
.eyebrow,
.label-mono {
  color: rgb(var(--ink-3));
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ── Surfaces ───────────────────────────────────────────────────────────────
   Elevation is permission, in two states: border only = read-only,
   shadow = pressable. No five-step ramp. */

.card { background: rgb(var(--sheet)); border: 1px solid rgb(var(--line)); border-radius: var(--r-surface); }
.card-pressable { background: rgb(var(--sheet)); border: 1px solid rgb(var(--line)); border-radius: var(--r-surface); box-shadow: var(--elev-1); }

/*
 * Cards used to run a cursor-tracking radial glow. Glows are out; a card is a
 * bordered sheet. The hover state is a border darkening, nothing more.
 */
.spotlight-card,
.glow-border {
  position: relative;
  background: rgb(var(--sheet));
  border-color: rgb(var(--line)) !important;
  border-radius: var(--r-surface);
  box-shadow: none;
  transition: border-color var(--t-2) var(--ease);
}
.spotlight-card:hover,
.glow-border:hover {
  border-color: rgb(var(--line-strong)) !important;
  box-shadow: none;
}
.spotlight-card::before,
.glow-border::before { content: none; }

/* ── Page rhythm ────────────────────────────────────────────────────────────
   Band the surfaces instead of drawing hairlines. The surface change is the
   edge — at low opacity on a light canvas a hairline does nothing. */

.band { background: rgb(var(--paper)); }
.band-sunk { background: rgb(var(--paper-sunk)); }
.section-tight { padding-top: 3rem; padding-bottom: 3rem; }
.section-tall { padding-top: 7rem; padding-bottom: 7rem; }

/*
 * Dividers, section glows, aurora blobs, film grain and page glows are all
 * deleted. Kept as no-ops so the ~60 existing call sites don't need removing
 * from markup — the elements collapse to nothing.
 */
.section-divider,
.section-glow-cyan,
.section-glow-violet,
.page-glow,
.grain,
.aurora-blob,
.blob-1,
.blob-2,
.blob-3 { display: none !important; }

/* Glow text was a text-shadow. There are no glows. */
.glow-text { text-shadow: none; }

/* ── Links ──────────────────────────────────────────────────────────────── */

.accent-link,
.prose-link {
  color: rgb(var(--yes-line));
  text-underline-offset: 2px;
}
.accent-link:hover,
.prose-link:hover { text-decoration: underline; opacity: 1; }

/* ── Per-card accent helpers ────────────────────────────────────────────────
   One brand color, rationed. The provider brand colors (Grok / Claude /
   Gemini / OpenAI) survive in exactly one place: the logo glyph itself, via
   --card-accent in the markup. Everything else — chips, labels, links,
   borders — is a token, so four cards read as one system. */

.accent-icon {
  color: rgb(var(--yes));
  background: rgb(var(--yes-tint));
  border: 1px solid rgb(var(--yes-line) / 0.3);
  border-radius: var(--r-control);
}
.accent-chip {
  border: 1px solid rgb(var(--line-strong));
  color: rgb(var(--ink-2));
  border-radius: var(--r-control);
  font-weight: 500;
}
.accent-label { color: rgb(var(--ink-3)); }

/*
 * Grok's mark is near-white (#e8e8e8), which was fine on the old black canvas
 * and is invisible on paper. It's the one provider logo that can't keep its
 * own color, so it takes ink instead. The other three clear the floor in both
 * themes and are left alone.
 */
svg path[fill="#e8e8e8"] { fill: rgb(var(--ink)); }

/* ── Buttons ────────────────────────────────────────────────────────────────
   Sentence case, no letterspacing, weight 500. Brand is a solid fill. */

.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.75rem 1.5rem;
  background: rgb(var(--yes));
  color: rgb(var(--ink-invert));
  font-weight: 500;
  font-size: 15px;
  border: 1px solid transparent;
  border-radius: var(--r-control);
  box-shadow: var(--elev-1);
  transition: background-color var(--t-1) var(--ease), transform var(--t-press) var(--ease);
}
.btn-primary:hover { background: rgb(var(--yes-hover)); }

.btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.75rem 1.5rem;
  background: rgb(var(--sheet));
  color: rgb(var(--ink));
  font-weight: 500;
  font-size: 15px;
  border: 1px solid rgb(var(--line-strong));
  border-radius: var(--r-control);
  transition: background-color var(--t-1) var(--ease), transform var(--t-press) var(--ease);
}
.btn-secondary:hover { background: rgb(var(--paper-sunk)); }

:where(.btn-primary, .btn-secondary, [data-press]):focus-visible {
  outline: 2px solid rgb(var(--yes-line));
  outline-offset: 2px;
}

/* Press feedback that works on touch, replacing mouse-only hover theater. */
[data-press],
.btn-primary,
.btn-secondary,
.magnetic { transition: transform var(--t-press) var(--ease); }
.is-pressed { transform: scale(0.985); }

/* The magnetic-cursor and CTA pulse effects are gone. */
.magnetic { transform: none !important; }
.cta-glow { animation: none !important; box-shadow: none !important; }

/* ── CTA panel ──────────────────────────────────────────────────────────────
   The page's one inverted band. .band-invert comes from tokens.css and is
   composed alongside this class in the markup. */

.cta-panel {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-sheet);
  border: 1px solid rgb(var(--line));
  background: rgb(var(--paper));
}

/* ── Terminals and code: the only legitimate monospace ──────────────────── */

.terminal {
  background: rgb(var(--paper-sunk));
  border: 1px solid rgb(var(--line));
  border-radius: var(--r-surface);
  overflow: hidden;
}
.terminal-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background: rgb(var(--sheet));
  border-bottom: 1px solid rgb(var(--line));
}
/* Traffic lights were skeuomorphic chrome. One neutral dot set instead. */
.t-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  flex-shrink: 0;
  background: rgb(var(--line-strong));
}
.terminal-title {
  flex: 1;
  margin-left: 8px;
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Menlo, monospace;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: rgb(var(--ink-3));
  text-transform: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.copy-btn {
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: rgb(var(--ink-2));
  border: 1px solid rgb(var(--line-strong));
  border-radius: var(--r-control);
  padding: 3px 10px;
  cursor: pointer;
  background: rgb(var(--sheet));
  flex-shrink: 0;
  transition: color var(--t-1) var(--ease), border-color var(--t-1) var(--ease);
}
.copy-btn:hover { color: rgb(var(--ink)); border-color: rgb(var(--ink-3)); }
.copy-btn.copied { color: rgb(var(--ok)); border-color: rgb(var(--ok)); }

.terminal pre { padding: 16px; overflow-x: auto; }
.terminal pre code,
pre code {
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Menlo, monospace;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: rgb(var(--ink-2));
  word-break: break-word;
  white-space: pre-wrap;
}
.t-cursor {
  display: inline-block;
  width: 7px;
  height: 13px;
  margin-left: 1px;
  background: rgb(var(--yes-line));
  vertical-align: -2px;
  animation: blink 0.9s step-end infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* ── Tabs ───────────────────────────────────────────────────────────────── */

.tab-btn {
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: rgb(var(--ink-2));
  border: 1px solid rgb(var(--line-strong));
  border-radius: var(--r-control);
  padding: 8px 16px;
  cursor: pointer;
  background: rgb(var(--sheet));
  transition: color var(--t-1) var(--ease), background-color var(--t-1) var(--ease),
    border-color var(--t-1) var(--ease), transform var(--t-press) var(--ease);
}
.tab-btn:hover { color: rgb(var(--ink)); background: rgb(var(--paper-sunk)); }
.tab-btn.active {
  color: rgb(var(--ink-invert));
  background: rgb(var(--yes));
  border-color: rgb(var(--yes));
}
.tab-panel { display: none; }
.tab-panel.active { display: block; }

/* ── Workflow timeline ──────────────────────────────────────────────────── */

.timeline { position: relative; }
.timeline-rail {
  position: absolute;
  left: 20px;
  top: 20px;
  bottom: 20px;
  width: 1px;
  background: rgb(var(--line));
}
.timeline-rail-progress {
  position: absolute;
  left: 20px;
  top: 20px;
  width: 2px;
  height: 0;
  background: rgb(var(--yes));
  box-shadow: none;
}
.timeline-node {
  width: 40px;
  height: 40px;
  border-radius: var(--r-control);
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgb(var(--sheet));
  border: 1px solid rgb(var(--line-strong));
  color: rgb(var(--ink-3));
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  position: relative;
  z-index: 2;
  flex-shrink: 0;
  transition: border-color var(--t-2) var(--ease), color var(--t-2) var(--ease);
}
.timeline-step.active .timeline-node {
  border-color: rgb(var(--yes));
  color: rgb(var(--yes));
  box-shadow: none;
}

/* ── Navigation ─────────────────────────────────────────────────────────── */

/* Selector is `nav`, not `#navbar`: the blog and admin pages ship a bare
   <nav> without the id, and both should get the same chrome. */
nav {
  background: rgb(var(--paper) / 0.85);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  will-change: transform;
  backface-visibility: hidden;
}
.nav-scrolled { border-bottom-color: rgb(var(--line)) !important; }

/*
 * Nav links were mono, uppercase and letterspaced. That combination is the
 * single strongest "this is a developer tool" signal there is, and this site
 * is read by people who are not developers. Sentence case, normal tracking.
 * Done here rather than in markup so all eight files change at once.
 */
nav a:not(.btn-primary):not(.btn-secondary),
#mobile-menu a {
  text-transform: none;
  letter-spacing: normal;
  font-size: 14px;
  color: rgb(var(--ink-2));
}
nav a:not(.btn-primary):not(.btn-secondary):hover,
#mobile-menu a:hover { color: rgb(var(--ink)); }
nav .font-display { font-size: 17px; letter-spacing: -0.01em; color: rgb(var(--ink)); }
/* The wordmark's accent letters and the current-page nav link keep the brand. */
nav .font-display span,
nav a.text-accent-cyan,
nav a.text-accent-brand { color: rgb(var(--yes-line)); }

.mobile-menu {
  max-height: 0;
  overflow: hidden;
  background: rgb(var(--paper));
  transition: max-height var(--t-3) var(--ease);
}
.mobile-menu.open { max-height: 380px; }

/*
 * backdrop-filter count for the whole system: 1 (the navbar). It forces a
 * compositing layer per node, and this page had it on every card.
 */
.backdrop-blur-sm,
.backdrop-blur,
.backdrop-blur-md,
.backdrop-blur-lg {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* Theme toggle */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1px solid rgb(var(--line-strong));
  border-radius: var(--r-control);
  background: rgb(var(--sheet));
  color: rgb(var(--ink-2));
  cursor: pointer;
  flex-shrink: 0;
  transition: color var(--t-1) var(--ease), border-color var(--t-1) var(--ease),
    transform var(--t-press) var(--ease);
}
.theme-toggle:hover { color: rgb(var(--ink)); border-color: rgb(var(--ink-3)); }
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-sun { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .icon-moon { display: none; }
}

/* ── Lightbox ───────────────────────────────────────────────────────────────
   The one backdrop-filter in the system is not spent here — a flat scrim is
   enough, and it keeps the count at zero outside the navbar. */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: rgb(12 14 15 / 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--t-2) var(--ease), visibility var(--t-2) var(--ease);
  cursor: zoom-out;
  -webkit-tap-highlight-color: transparent;
}
.lightbox.active { opacity: 1; visibility: visible; }
.lightbox img {
  max-width: 95vw;
  max-height: 90vh;
  object-fit: contain;
  border-radius: var(--r-surface);
  transform: scale(0.97);
  transition: transform var(--t-2) var(--ease);
}
.lightbox.active img { transform: scale(1); }
.lightbox-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 36px;
  height: 36px;
  border: 1px solid rgb(255 255 255 / 0.25);
  border-radius: var(--r-control);
  background: rgb(0 0 0 / 0.5);
  color: #fff;
  font-size: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.zoomable { cursor: zoom-in; }

/* ── Motion ─────────────────────────────────────────────────────────────────
   Fires when data changed or to show where something came from. Never on
   scroll — so the old fade-in-on-scroll is now a no-op that renders content
   immediately rather than animating it in. */

.fade-in { opacity: 1; transform: none; }
#cycle-word { display: inline-block; min-width: 5.5ch; }

@media (prefers-reduced-motion: reduce), (update: slow) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
