/* ===================================================================
   Winnemac Labs: lab notes posts and the notes index
   Loaded *after* css/style.css, which provides the design tokens.
   Used by the hand-authored pages in /notes/.
   =================================================================== */

/* Article pages have no YAML loaders to wait on, so they never receive the
   .content-ready class that style.css uses to fade the body in. Override the
   hidden default here so the page renders even if JavaScript never runs. */
body { opacity: 1; }

/* ── Page shell ──────────────────────────────────────────────────── */
.post-page {
  max-width: 1280px;
  margin: 0 auto;
  padding: 9rem 2rem 0;
}

/* Reading column. 68ch keeps prose in the comfortable 60–75 character range. */
.post-article {
  max-width: 68ch;
  margin: 0 auto;
}

/* ── Back link ───────────────────────────────────────────────────── */
.post-back {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 3rem;
  transition: color 0.2s var(--ease-out);
}

.post-back:hover { color: var(--accent); }

/* ── Article header ──────────────────────────────────────────────── */
/* The only gap between the byline strip and the first heading. .post-body adds
   no padding of its own, and its first child gets its top margin zeroed, so
   this number is the whole story rather than one of three stacking values. */
.post-header { margin-bottom: 4rem; }

.post-header .section-tag { margin-bottom: 1.25rem; }

.post-title {
  font-size: clamp(2.1rem, 4.4vw, 3.4rem);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1.06;
  color: var(--text);
  margin-bottom: 1.5rem;
}

/* The deck: one paragraph of larger-than-body text under the title. */
.post-deck {
  font-size: clamp(1.1rem, 1.6vw, 1.3rem);
  line-height: 1.6;
  color: var(--text-2);
  font-weight: 300;
}

/* ── Byline / metadata strip ─────────────────────────────────────── */
.post-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 2.5rem;
  padding: 1.5rem 0;
  margin-top: 2.5rem;
  border-top: 1px solid var(--rule-2);
  border-bottom: 1px solid var(--rule-2);
}

.post-meta-item {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.post-meta-label {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* Author photo beside the byline; the name next to it is the label. */
.post-author {
  flex-direction: row;
  align-items: center;
  gap: 0.85rem;
}

.post-author-photo {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--rule-2);
  background: var(--bg-2);
}

.post-meta-value {
  font-size: 0.95rem;
  color: var(--text);
  font-weight: 500;
}

/* ── Header pulse (decorative current trace) ─────────────────────── */
.post-pulse {
  height: 56px;
  margin-top: 2rem;
  overflow: hidden;
  /* Fade in and out at the edges so the loop has no visible seam. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.post-pulse svg { display: block; width: 100%; height: 100%; }

.post-pulse path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-linejoin: round;
  opacity: 0.8;
}

.post-pulse-track { animation: post-pulse-slide 7s linear infinite; }

@keyframes post-pulse-slide {
  from { transform: translateX(0); }
  to   { transform: translateX(-600px); }
}

@media (prefers-reduced-motion: reduce) {
  .post-pulse-track { animation: none; }
}

/* ── Prose ───────────────────────────────────────────────────────── */
.post-body > * + * { margin-top: 1.5rem; }

/* Headings carry a large top margin to separate sections. On the first element
   there is nothing above to separate from, so it just reads as a dead gap. */
.post-body > *:first-child { margin-top: 0; }

.post-body p {
  font-size: 1.06rem;
  line-height: 1.75;
  color: var(--text-2);
}

.post-body h2 {
  font-size: clamp(1.5rem, 2.4vw, 1.95rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: var(--text);
  margin-top: 4rem;
}

.post-body h3 {
  font-size: 1.2rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
  margin-top: 2.75rem;
}

.post-body h2 + p,
.post-body h3 + p { margin-top: 1rem; }

.post-body strong { color: var(--text); font-weight: 600; }

.post-body a:not(.btn-primary):not(.btn-ghost) {
  color: var(--accent);
  border-bottom: 1px solid var(--rule);
  transition: border-color 0.2s var(--ease-out);
}

.post-body a:not(.btn-primary):not(.btn-ghost):hover {
  border-bottom-color: var(--accent);
}

.post-body ul,
.post-body ol {
  padding-left: 1.4rem;
  color: var(--text-2);
}

.post-body li {
  font-size: 1.06rem;
  line-height: 1.75;
  margin-bottom: 0.6rem;
}

.post-body li::marker { color: var(--accent); }

/* ── Figures ─────────────────────────────────────────────────────── */
.post-figure {
  margin-top: 3rem;
  margin-bottom: 3rem;
}

.post-figure img,
.post-figure video {
  width: 100%;
  height: auto;
  border: 1px solid var(--rule-2);
  border-radius: 12px;
  background: var(--bg-2);
}

.post-figure figcaption {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  line-height: 1.6;
  letter-spacing: 0.03em;
  color: var(--text-3);
  margin-top: 0.85rem;
}

/* Two images side by side, for scale or before/after comparisons. Deliberately
   stays two-up at every width: stacking these would destroy the comparison the
   figure exists to make. Source images of differing aspect ratio are cropped to
   a common 2:3 so the pair reads as one unit. */
.post-figure-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.post-figure-pair img,
.post-figure-pair video {
  display: block;
  aspect-ratio: 2 / 3;
  object-fit: cover;
}

@media (max-width: 768px) {
  .post-figure-pair { gap: 0.6rem; }
}

/* ── Pull quote ──────────────────────────────────────────────────── */
.post-quote {
  margin: 3rem 0;
  padding-left: 1.75rem;
  border-left: 2px solid var(--accent);
}

.post-quote p {
  font-size: clamp(1.2rem, 1.9vw, 1.5rem);
  line-height: 1.5;
  letter-spacing: -0.02em;
  font-weight: 300;
  color: var(--text);
}

.post-quote cite {
  display: block;
  margin-top: 1rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  font-style: normal;
  color: var(--text-3);
}

/* ── Callout ─────────────────────────────────────────────────────── */
.post-callout {
  margin: 3rem 0;
  padding: 1.75rem 2rem;
  background: var(--bg-2);
  border: 1px solid var(--rule-2);
  border-radius: 12px;
}

.post-callout > * + * { margin-top: 0.75rem; }

.post-callout h3 {
  margin-top: 0;
  font-size: 0.72rem;
  font-family: var(--font-mono);
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}

.post-callout p { font-size: 0.98rem; }

/* ── Spec table ──────────────────────────────────────────────────── */
.post-specs {
  margin: 3rem 0;
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--rule-2);
  border-radius: 12px;
  overflow: hidden;
}

.post-specs th,
.post-specs td {
  text-align: left;
  padding: 0.9rem 1.25rem;
  border-bottom: 1px solid var(--rule-2);
  font-size: 0.95rem;
}

.post-specs tr:last-child th,
.post-specs tr:last-child td { border-bottom: none; }

.post-specs th {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  font-weight: 400;
  color: var(--text-3);
  width: 40%;
  background: var(--bg-2);
}

.post-specs td { color: var(--text); }

/* Column-header variant, for tables that read left-to-right rather than as
   key/value pairs. Both columns get the header treatment in the top row. */
.post-specs thead th {
  width: auto;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  border-bottom: 1px solid var(--rule);
}

/* Row-spanning cells in the first column stay top-aligned against their group. */
.post-specs tbody th[rowspan] { vertical-align: top; }

/* Add --cols when the first column carries data rather than a field label.
   The default th treatment (small grey mono on a grey fill) is meant to
   recede behind its value; as a data column it just reads as unreadable. */
.post-specs--cols tbody th {
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
  color: var(--text);
  background: none;
}

/* Tables can exceed the reading column on small screens. */
.post-table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.post-table-scroll .post-specs { margin: 0; min-width: 420px; }

/* ── Code ────────────────────────────────────────────────────────── */
.post-body code {
  font-family: var(--font-mono);
  font-size: 0.85em;
  padding: 0.15em 0.4em;
  background: var(--bg-3);
  border-radius: 4px;
  color: var(--accent);
}

.post-body pre {
  margin: 2.5rem 0;
  padding: 1.5rem;
  background: var(--bg-2);
  border: 1px solid var(--rule-2);
  border-radius: 12px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.post-body pre code {
  padding: 0;
  background: none;
  color: var(--text);
  font-size: 0.85rem;
  line-height: 1.7;
}

/* ── Closing CTA ─────────────────────────────────────────────────── */
.post-cta {
  max-width: 68ch;
  margin: 6rem auto 0;
  padding: 3rem 0 7rem;
  border-top: 1px solid var(--rule-2);
  text-align: center;
}

.post-cta h2 {
  font-size: clamp(1.6rem, 2.8vw, 2.2rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.15;
  margin-bottom: 1rem;
}

.post-cta p {
  font-size: 1.02rem;
  line-height: 1.65;
  color: var(--text-2);
  margin-bottom: 2rem;
}

/* ── Mobile ──────────────────────────────────────────────────────── */
@media (max-width: 768px) {
  .post-page { padding: 7rem 1.5rem 0; }

  .post-back { margin-bottom: 2rem; }

  .post-meta { gap: 1.5rem 2rem; }

  .post-body { padding-top: 2.5rem; }

  .post-body h2 { margin-top: 3rem; }

  .post-callout { padding: 1.5rem; }

  .post-quote { padding-left: 1.25rem; }

  .post-cta { padding-bottom: 5rem; }
}

/* ── Lab Notes index page (/notes/) ────────────────────────────────────── */
.notes-page {
  padding-bottom: 7rem;
}

.notes-page-header {
  max-width: 68ch;
  margin-bottom: 3.5rem;
}

.notes-page-header .section-tag { margin-bottom: 1.25rem; }

.notes-empty {
  padding: 2.5rem 0;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: 0.8rem;
}

.notes-research {
  /* Overrides the generic section padding/max-width from style.css. */
  max-width: none;
  padding: 0;
  margin-top: 6rem;
  scroll-margin-top: 90px;
}

.notes-research[hidden] { display: none; }

.notes-research-header {
  max-width: 68ch;
  margin-bottom: 2.5rem;
}

.notes-research-title {
  font-size: clamp(1.6rem, 2.8vw, 2.2rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.15;
  color: var(--text);
  margin-bottom: 1rem;
}

.notes-research-intro {
  font-size: 1.02rem;
  line-height: 1.7;
  color: var(--text-2);
}

@media (max-width: 768px) {
  .notes-page { padding-bottom: 5rem; }
  .notes-research { margin-top: 4rem; }
}

.nav-links a[aria-current="page"] { color: var(--text); }

/* ── Battery-life calculator (js/battery-calculator.js) ──────────── */
/* Chart colors: validated pair for the page background (#F5F4F0) with the
   dataviz palette checker: blue = sleeping, terracotta = waking. */
.calc,
.trace,
.conn,
.mip {
  --calc-sleep: #1F5FA3;
  --calc-wake:  #C9673F;
  padding: 1.75rem;
  background: var(--bg-2);
  border: 1px solid var(--rule-2);
  border-radius: 12px;
}

.calc[hidden],
.trace[hidden],
.conn[hidden] { display: none; }

.calc-head { margin-bottom: 1.25rem; }

.calc-eyebrow {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.4rem;
}

.post-body .calc-title {
  margin-top: 0;
  font-size: 1.35rem;
}

.post-body .calc-sub {
  margin-top: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--text-2);
}

/* Presets: one row of pills above the controls. */
.calc-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

.calc-preset {
  font: inherit;
  font-size: 0.82rem;
  padding: 0.45rem 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--rule);
  background: var(--bg);
  color: var(--text-2);
  cursor: pointer;
  transition: border-color 0.2s var(--ease-out), color 0.2s var(--ease-out), background 0.2s var(--ease-out);
}

.calc-preset:hover { border-color: var(--accent); color: var(--text); }

.calc-preset[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.calc-preset:focus-visible,
.calc input:focus-visible,
.calc select:focus-visible,
.calc-unit-input input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.calc-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
}

.calc-controls { display: grid; gap: 1.1rem; }

.calc-field label {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.85rem;
  color: var(--text-2);
  margin-bottom: 0.35rem;
}

.calc-field output {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--text);
}

.calc input[type="range"] {
  width: 100%;
  accent-color: var(--accent);
  height: 1.5rem; /* generous hit target */
}

.calc select {
  width: 100%;
  font: inherit;
  font-size: 0.88rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
}

.calc-custom {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-top: 0.75rem;
}

.calc-custom[hidden] { display: none; }

.calc-custom label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.8rem;
  color: var(--text-2);
}

.calc-unit-input {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--text-3);
}

.calc-unit-input input {
  width: 100%;
  min-width: 0;
  font: inherit;
  font-size: 0.88rem;
  color: var(--text);
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--bg);
}

.calc-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.calc-stat {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 1rem;
  background: var(--bg);
  border: 1px solid var(--rule-2);
  border-radius: 10px;
}

.calc-stat-label {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}

.calc-stat-value {
  /* Sized for the reading column: "6.9 years" stays on one line. */
  font-size: clamp(1.35rem, 2.2vw, 1.7rem);
  white-space: nowrap;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.calc-stat-note {
  font-size: 0.78rem;
  color: var(--text-3);
}

/* Sleep/wake split: one stacked bar, 2px surface gap between the parts. */
.calc-split { margin-top: 1.25rem; }

.calc-split-bar {
  display: flex;
  gap: 2px;
  height: 12px;
}

.calc-split-bar span {
  min-width: 3px;
  flex-basis: 0;
  transition: flex-grow 0.25s var(--ease-out);
}

.calc-split-sleep { background: var(--calc-sleep); border-radius: 4px 0 0 4px; }
.calc-split-wake  { background: var(--calc-wake);  border-radius: 0 4px 4px 0; }

.calc-split-legend {
  display: flex;
  justify-content: space-between;
  margin-top: 0.5rem;
  font-size: 0.8rem;
  color: var(--text-2);
}

.calc-split-legend b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }

.calc-key {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  margin-right: 0.4rem;
  vertical-align: -1px;
}

.calc-key--sleep { background: var(--calc-sleep); }
.calc-key--wake  { background: var(--calc-wake); }

/* Chart */
.calc-chart {
  position: relative;
  margin-top: 1.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule-2);
}

.post-figure .calc-svg {
  display: block;
  width: 100%;
  height: auto;
  border: none;
  border-radius: 0;
  background: none;
}

.calc-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  margin-bottom: 0.75rem;
  font-size: 0.8rem;
  color: var(--text-2);
}

.calc-swatch {
  display: inline-block;
  width: 18px;
  height: 0;
  margin-right: 0.45rem;
  vertical-align: 3px;
  border-top: 2px solid var(--text);
}

.calc-swatch--total { border-top-width: 2.5px; }
.calc-swatch--sleep { border-top: 2px dashed var(--calc-sleep); }
.calc-swatch--wake  { border-top: 2px dashed var(--calc-wake); }

.calc-grid line { stroke: var(--rule-2); stroke-width: 1; }

.calc-tick,
.calc-axis-title,
.calc-label {
  font-family: var(--font-mono);
  font-size: 11px;
  fill: var(--text-3);
}

.calc-tick--y { text-anchor: end; }
.calc-tick--x,
.calc-axis-title { text-anchor: middle; }
.calc-axis-title { fill: var(--text-2); }

.calc-label { fill: var(--text-2); }
.calc-label--end { text-anchor: end; }

.calc-line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.calc-line--sleep { stroke: var(--calc-sleep); stroke-dasharray: 5 4; }
.calc-line--wake  { stroke: var(--calc-wake); stroke-dasharray: 5 4; }
.calc-line--total { stroke: var(--text); stroke-width: 2.5; }

.calc-dot { fill: var(--text); stroke: var(--bg-2); stroke-width: 2; }
.calc-dot--hover { fill: var(--accent); }

.calc-even { stroke: var(--text-3); stroke-width: 1; stroke-dasharray: 1 3; }

.calc-crosshair { stroke: var(--text-3); stroke-width: 1; stroke-dasharray: 2 3; }

.calc-hit { fill: transparent; cursor: crosshair; }

.calc-tip {
  position: absolute;
  transform: translate(-50%, -100%);
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.5rem 0.7rem;
  background: var(--text);
  color: #fff;
  border-radius: 8px;
  font-size: 0.8rem;
  line-height: 1.35;
  white-space: nowrap;
  pointer-events: none;
}

.calc-tip[hidden] { display: none; }

.calc-tip-k {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  opacity: 0.75;
}

@media (max-width: 768px) {
  .calc, .trace, .conn, .mip { padding: 1.25rem; }
  .calc-body { grid-template-columns: 1fr; gap: 1.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  .calc-split-bar span,
  .calc-preset { transition: none; }
}

/* ── Measured wake-up trace (js/wake-trace.js) ───────────────────── */
.trace-chart { position: relative; }

.trace-swatch--avg  { border-top: 2px solid var(--calc-sleep); }

.trace-avg {
  fill: none;
  stroke: var(--calc-sleep);
  stroke-width: 1.5;
  stroke-linejoin: round;
}

.trace-band rect { fill: var(--bg-3); opacity: 0.45; transition: opacity 0.15s var(--ease-out); }
.trace-band--alt rect { opacity: 0.25; }
.trace-band.is-active rect { fill: var(--calc-wake); opacity: 0.18; }

.trace-band-num {
  font-family: var(--font-mono);
  font-size: 11px;
  fill: var(--text-3);
  text-anchor: middle;
}

.trace-band.is-active .trace-band-num { fill: var(--text); font-weight: 700; }

/* Energy by phase */
.trace-phases {
  list-style: none;
  margin-top: 1.25rem;
  padding: 0;
  display: grid;
  gap: 0.15rem;
}

.post-body .trace-phases { padding-left: 0; }

.trace-phase {
  display: grid;
  grid-template-columns: 1.5rem minmax(8rem, 16rem) 3.5rem minmax(0, 1fr) 4.5rem;
  align-items: center;
  gap: 0.75rem;
  padding: 0.4rem 0.5rem;
  border-radius: 6px;
  font-size: 0.85rem;
  color: var(--text-2);
  margin: 0;
  cursor: default;
}

.post-body .trace-phase { font-size: 0.85rem; line-height: 1.4; margin-bottom: 0; }
.post-body .trace-phase::marker { content: none; }

.trace-phase.is-active { background: var(--bg); color: var(--text); }
.trace-phase:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.trace-phase-num {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-3);
}

.trace-phase-dur,
.trace-phase-e {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

.trace-phase-e { text-align: right; color: var(--text); }

.trace-phase-bar {
  height: 8px;
  background: var(--bg-3);
  border-radius: 4px;
  overflow: hidden;
}

.trace-phase-bar span {
  display: block;
  height: 100%;
  background: var(--calc-wake);
  border-radius: 0 4px 4px 0;
}

@media (max-width: 600px) {
  .trace-phase {
    grid-template-columns: 1.25rem minmax(0, 1fr) 3rem 4rem;
    grid-template-areas: "num name dur e" ". bar bar bar";
    row-gap: 0.3rem;
  }
  .trace-phase-num { grid-area: num; }
  .trace-phase-name { grid-area: name; }
  .trace-phase-dur { grid-area: dur; }
  .trace-phase-e { grid-area: e; }
  .trace-phase-bar { grid-area: bar; }
}

@media (prefers-reduced-motion: reduce) {
  .trace-band rect { transition: none; }
}

/* ── Stay connected vs. reconnect (js/connection-chart.js) ───────── */
/* Same color roles as the calculator: steady "wake cheap" cost in
   terracotta, "sleep deep" in blue. */
.conn-chart { position: relative; }
.conn-line--connected { stroke: var(--calc-wake); }
.conn-line--reconnect { stroke: var(--calc-sleep); }
.conn-swatch--connected { border-top: 2px solid var(--calc-wake); }
.conn-swatch--reconnect { border-top: 2px solid var(--calc-sleep); }
.calc-tip b { font-weight: 700; }

/* ── E-paper vs. Sharp MIP (js/display-chart.js) ─────────────────── */
/* E-paper sleeps deep and pays per update (blue); MIP holds a steady
   cost (terracotta): the same roles as the other charts. */
.mip-chart { position: relative; }
.mip-chart[hidden] { display: none; }
.post-figure.mip img { border: none; background: none; }
.mip-line--epaper { stroke: var(--calc-sleep); }
.mip-line--mip { stroke: var(--calc-wake); }
.mip-swatch--epaper { border-top: 2px solid var(--calc-sleep); }
.mip-swatch--mip { border-top: 2px solid var(--calc-wake); }
.post-figure.mip figcaption { margin-top: 1rem; }
.post-figure.mip img[hidden] { display: none; }

/* ── Table of contents (js/post-page.js) ─────────────────────────── */
.post-toc {
  display: none;
  position: fixed;
  top: 120px;
  width: 13rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s var(--ease-out);
}

@media (min-width: 1200px) {
  .post-toc { display: block; }
  .post-toc.is-visible { opacity: 1; pointer-events: auto; }
  .post-toc.is-cramped { display: none; }
}

.post-toc ol {
  list-style: none;
  padding: 0 0 0 0.9rem;
  margin: 0;
  border-left: 1px solid var(--rule-2);
  display: grid;
  gap: 0.55rem;
}

.post-toc a {
  display: block;
  font-size: 0.82rem;
  line-height: 1.35;
  color: var(--text-3);
  transition: color 0.2s var(--ease-out);
}

.post-toc a:hover { color: var(--text); }

.post-toc a[aria-current="location"] {
  color: var(--accent);
  font-weight: 500;
}

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

/* Jumped-to headings clear the fixed nav. */
.post-body > h2 { scroll-margin-top: 90px; }

@media (prefers-reduced-motion: reduce) {
  .post-toc, .post-toc a { transition: none; }
}

/* ── Scroll-in figures (post-page.js adds .is-in) ────────────────── */
/* Sleep floor bars: a linear scale on purpose; the custom bar is a sliver. */
.bars {
  display: grid;
  gap: 0.75rem;
  padding: 1.5rem 1.75rem;
  background: var(--bg-2);
  border: 1px solid var(--rule-2);
  border-radius: 12px;
}

.bars-title {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}

.bar-row {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr) 5rem;
  align-items: center;
  gap: 1rem;
  font-size: 0.9rem;
  color: var(--text-2);
}

.bar-track { display: block; height: 14px; }

.bar-fill {
  display: block;
  height: 100%;
  width: calc(var(--v) * 100%);
  min-width: 3px;
  border-radius: 0 4px 4px 0;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1.4s var(--ease-out);
}

.bar-fill--devkit { background: var(--text-3); }
.bar-fill--custom { background: #1F5FA3; transition-delay: 0.5s; }
.bars.is-in .bar-fill { transform: scaleX(1); }

.bar-value {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--text);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 768px) {
  .bars { padding: 1.25rem; }
  .bar-row { grid-template-columns: 6rem minmax(0, 1fr) 4.25rem; gap: 0.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  .bar-fill { transform: none; transition: none; }
}

/* ── Energy-harvesting icons (decorative, CSS-animated) ──────────── */
.harvest-icon {
  display: inline-block; /* the reset makes svg a block */
  width: 22px;
  height: 22px;
  margin-right: 0.6rem;
  vertical-align: -5px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.6;
  stroke-linecap: round;
  overflow: visible;
}

.harvest-icon--sun circle { fill: var(--accent); stroke: none; }
.harvest-icon--waves circle { fill: var(--accent); stroke: none; }

.harvest-rays {
  transform-origin: 12px 12px;
  animation: harvest-spin 14s linear infinite;
}

.harvest-arc { animation: harvest-pulse 2.4s ease-in-out infinite; }
.harvest-arc--2 { animation-delay: 0.3s; }
.harvest-arc--3 { animation-delay: 0.6s; }

.harvest-shimmer { animation: harvest-rise 2.8s ease-in-out infinite; }

@keyframes harvest-spin  { to { transform: rotate(360deg); } }
@keyframes harvest-pulse { 0%, 100% { opacity: 0.25; } 40% { opacity: 1; } }
@keyframes harvest-rise  { 0%, 100% { transform: translateY(1px); opacity: 0.7; } 50% { transform: translateY(-1.5px); opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .harvest-rays, .harvest-arc, .harvest-shimmer { animation: none; }
}

/* ── Energy used in real time (js/energy-meter.js) ───────────────── */
.meter {
  padding: 1.5rem 1.75rem;
  background: var(--bg-2);
  border: 1px solid var(--rule-2);
  border-radius: 12px;
}

.meter-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

.meter-title,
.meter-time {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}

.meter-time { text-align: right; margin-top: 0.75rem; text-transform: none; letter-spacing: 0.04em; }

.meter-toggle {
  font: inherit;
  font-size: 0.78rem;
  padding: 0.3rem 0.8rem;
  border-radius: 999px;
  border: 1px solid var(--rule);
  background: var(--bg);
  color: var(--text-2);
  cursor: pointer;
}

.meter-toggle:hover { color: var(--text); border-color: var(--accent); }
.meter-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.meter-rows { display: grid; gap: 0.5rem; }

.meter-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 1rem;
  align-items: baseline;
  font-size: 0.9rem;
  color: var(--text-2);
}

.meter-name b {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 400;
  margin-left: 0.4rem;
}

.meter-val {
  font-family: var(--font-mono);
  font-size: 1.02rem;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Leading zeros recede so each row's live digits stand out, while staying
   at the AA text contrast floor (muted grey, 4.6:1 on the panel). */
.meter-val .z { color: var(--text-3); }

/* Ours in blue; everyday devices stay neutral. */
.meter-row--ours,
.meter-row--ours .meter-val { color: #1F5FA3; }

@media (max-width: 600px) {
  .meter { padding: 1.25rem; }
  .meter-row { grid-template-columns: 1fr; gap: 0.1rem; }
  .meter-val { font-size: 0.9rem; }
}

/* ── "Why ultra low power" icons (same base as the harvesting icons) ── */
.reason-icon--pin circle { fill: none; stroke: var(--accent); }
.reason-bounce { animation: reason-bounce 2.2s ease-in-out infinite; }
.reason-shrink { transform-origin: 12px 12px; animation: reason-shrink 2.6s ease-in-out infinite; }
.reason-press { animation: reason-press 2.6s ease-in-out infinite; }
.reason-charge rect { fill: var(--accent); stroke: none; animation: reason-charge 3s ease-in-out infinite; }
.reason-charge rect:nth-child(2) { animation-delay: 0.25s; }
.reason-charge rect:nth-child(3) { animation-delay: 0.5s; }

@keyframes reason-bounce { 0%, 100% { transform: translateY(0); } 45% { transform: translateY(-2.5px); } }
@keyframes reason-shrink { 0%, 100% { transform: scale(1); } 50% { transform: scale(0.7); } }
@keyframes reason-press  { 0%, 100% { transform: translateX(0); opacity: 0.6; } 50% { transform: translateX(0); opacity: 1; } }
@keyframes reason-charge { 0%, 70%, 100% { opacity: 1; } 85% { opacity: 0.35; } }

@media (prefers-reduced-motion: reduce) {
  .reason-bounce, .reason-shrink, .reason-press, .reason-charge rect { animation: none; }
}

.nowrap { white-space: nowrap; }
