/* ═══════════════════════════════════════════════════════════════════
   TANSEI EDITORIAL — blog article template (drop 12). Loads after
   editorial-base.css. Two beats: the cover spread (photo + black title
   panel), then the white body on an offset measure, closing on the
   full-bleed "Keep reading" split. SF throughout — no serif (the
   drop-7 serif direction is superseded by this handoff).
   Prose markup is untouched; this sheet only dresses it.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  --prose: #2a2a32;
  --block: #eef1f6;
  --figbox: #dfe3ea;
}
[data-theme='dark'] {
  --prose: #c9c9cf;
  --block: #17171b;
  --figbox: #1b1b20;
}

/* ── Reading progress ─────────────────────────────────────────────── */
.progress-bar {
  position: fixed; top: 0; left: 0; z-index: 140;
  height: 2px; width: 0;
  background: var(--accent);
}

/* ── Cover ────────────────────────────────────────────────────────── */
/* Full-panel cover. The photograph beside the title was retired 9 Aug: the
   article images were AI-generated and the founder would rather show nothing
   than something she isn't sure of. One dark band now carries the title, with
   the copy held to the same 1400px measure the rest of the site uses. */
.ba-cover { display: block; }
/* The split survives the photograph's removal by splitting the TYPE instead:
   title on the left, standfirst answering it on the right, one rule under
   both. Keeps the editorial spread without needing an image to fill a half. */
.ba-panel {
  background: #0e0e10;
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
  column-gap: 90px; align-content: center;
  padding: 132px max(40px, calc((100vw - 1400px) / 2)) 120px;
  box-sizing: border-box;
}
.ba-panel > .ba-back { grid-column: 1 / -1; grid-row: 1; justify-self: start; }
.ba-panel > .ba-cats { grid-column: 1; grid-row: 2; }
.ba-panel > h1 { grid-column: 1; grid-row: 3; }
.ba-panel > .ba-stand { grid-column: 2; grid-row: 3; align-self: end; margin: 0 0 10px; }
.ba-panel > .ba-meta { grid-column: 1 / -1; grid-row: 4; }
.ba-back {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.22em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}
.ba-cats {
  display: block; margin-top: 48px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.24em; text-transform: uppercase;
  color: #f4629f;
}
.ba-panel h1 {
  margin: 22px 0 0; max-width: 15ch;
  font-size: clamp(40px, 4.2vw, 60px); font-weight: 200; letter-spacing: -0.048em; line-height: 1;
  color: #f5f5f7; text-wrap: pretty;
}
.ba-stand {
  margin: 26px 0 0; max-width: 34ch;
  font-size: 22px; font-weight: 300; letter-spacing: -0.016em; line-height: 1.42;
  color: #a8a8b0; text-wrap: pretty;
}
.ba-meta {
  align-self: stretch;
  margin-top: 48px; padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 24px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  color: #8d8d93;
}
.ba-meta a { color: #f4629f; }
/* One text run, not five flex children: on a phone the row used to break
   into four ragged lines because each item wrapped as a block. As words it
   wraps like a sentence and holds one line almost everywhere. */
.ba-line { margin: 0; line-height: 2.2; }
/* Each item wraps whole; without this "17 MIN / READ" splits across the break. */
.ba-line time, .ba-read, .ba-author { white-space: nowrap; }
/* The source credit sits apart from the byline cluster: right-aligned where
   there is room, dropping to its own line on a phone rather than breaking
   the byline up. */
.ba-seen { margin-left: auto; white-space: nowrap; }
@media (max-width: 700px) { .ba-seen { margin-left: 0; } }
.ba-dot { margin: 0 2px; color: #55555e; }
/* The byline is underlined, so a wrapped line needs room or the rule sits on
   top of the words below it. Tighten the tracking on narrow screens too, which
   buys back enough width to keep this on one line on most phones. */
@media (max-width: 430px) {
  .ba-meta { letter-spacing: 0.12em; font-size: 9.5px; }
  .ba-line { line-height: 2.4; }
}

/* ── Body — offset measure ────────────────────────────────────────── */
main { padding: 0; }
.ba-body { padding: 104px 40px 40px; }
article.post {
  max-width: 820px; margin: 0 auto;
  padding: 0 0 0 104px; box-sizing: content-box;
}

/* Prose: SF, retuned leading for sans. */
article.post p {
  margin: 24px 0 0;
  font-size: 20px; font-weight: 300; letter-spacing: -0.014em; line-height: 1.7;
  color: var(--prose); text-wrap: pretty;
}
article.post > p:first-of-type {
  margin-top: 0;
  font-size: 22px; letter-spacing: -0.016em; line-height: 1.6;
}
article.post h2 {
  margin: 76px 0 0; max-width: 24ch;
  font-size: clamp(30px, 3.2vw, 38px); font-weight: 200; letter-spacing: -0.038em; line-height: 1.08;
  color: var(--ink); text-wrap: pretty;
}
article.post h3 {
  margin: 34px 0 0; max-width: 34ch;
  font-size: 22px; font-weight: 400; letter-spacing: -0.022em; line-height: 1.3;
  color: var(--ink); text-wrap: pretty;
}
article.post h2 + p, article.post h3 + p { margin-top: 18px; }
article.post strong { font-weight: 500; color: var(--ink); }
article.post p a { color: var(--accent); }
/* The source's standalone bold statements set as display type. */
article.post blockquote {
  margin: 60px 0; padding: 0; max-width: 26ch;
  font-size: clamp(27px, 3vw, 34px); font-weight: 200; letter-spacing: -0.036em; line-height: 1.2;
  color: var(--ink); text-wrap: pretty;
}
article.post blockquote p { margin: 0; font: inherit; color: inherit; }
/* Lists: no bullets — zero-padded mono index in a hanging grid. */
article.post ul, article.post ol {
  margin: 32px 0 0; padding: 0; list-style: none;
  counter-reset: ba-li;
}
article.post li {
  counter-increment: ba-li;
  display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 14px;
  align-items: baseline; margin-top: 18px;
  font-size: 19px; font-weight: 300; letter-spacing: -0.014em; line-height: 1.6;
  color: var(--prose); text-wrap: pretty;
}
article.post li::before {
  content: '0' counter(ba-li);
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em;
  color: var(--idx);
}
article.post hr { border: 0; border-top: 1px solid var(--cell); margin: 60px 0 36px; }

/* ── Figures ──────────────────────────────────────────────────────── */
.post-figure, .post-hero, .fig-shelf { margin: 64px 0 0; }
.post-figure > div, .ba-figbox { border-radius: 22px; overflow: hidden; background: var(--figbox); }
/* Photo figures only. .fig-shelf is a built UI mock, not a photograph — its
   18px app icon must not be stretched to the column width. */
.post-figure img, .post-hero img {
  display: block; width: 100%; height: auto;
  border-radius: 22px; background: var(--figbox);
}

/* Built shelf mock. The component lived in blog.css, which these editorial
   pages never load, against tokens (--line, --fill, --ink-2) that do not
   exist here — so it rendered as unstyled stacked divs with a blown-up icon.
   Ported to the editorial tokens. */
.fig-shelf {
  margin: 64px auto 0; max-width: 340px; padding: 14px;
  border: 1px solid var(--cell); border-radius: 18px;
  background: var(--bg);
  box-shadow: 0 20px 44px -30px rgba(0, 0, 0, 0.3);
}
.fig-shelf .fs-head {
  display: flex; align-items: center; gap: 8px;
  padding: 2px 4px 12px; border-bottom: 1px solid var(--cell);
}
.fig-shelf .fs-head img { width: 18px; height: 18px; border-radius: 5px; }
.fig-shelf .fs-head span { font-size: 13px; font-weight: 600; color: var(--ink); }
.fig-shelf .fs-row { display: flex; align-items: center; gap: 12px; padding: 10px 4px; }
.fig-shelf .fs-row + .fs-row { border-top: 1px solid var(--cell); }
.fig-shelf .fs-chip {
  width: 34px; height: 34px; border-radius: 9px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.fig-shelf .fs-chip.color { background: #007aff; }
.fig-shelf .fs-chip.link { background: rgba(217, 46, 118, 0.12); color: var(--accent); }
.fig-shelf .fs-chip.img { background: var(--figbox); border: 1px solid var(--cell); color: var(--ink2); }
.fig-shelf .fs-t { font-size: 13px; line-height: 1.3; color: var(--ink); }
.fig-shelf .fs-s { margin-top: 2px; font-size: 11px; color: var(--ink3); }
.post-figure figcaption, .post-hero figcaption, .fig-shelf figcaption {
  margin-top: 16px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; line-height: 1.8;
  color: var(--idx);
}
.reveal { opacity: 1; transform: none; }

/* ── In-article reel ──────────────────────────────────────────────
   A 9:16 clip in an 820px prose column has to be reined in or it runs
   taller than the viewport. Capped narrow and centred; the whole frame is
   a link to /get, with the sound toggle layered above that link so the
   two never fight for the same click. */
.post-reel { margin: 64px 0 0; }
/* The frame IS the control: the whole clip toggles sound. Clicking a video to
   navigate away is unexpected, so the download is its own link in the caption.
   Width scales a little with the viewport, but stays capped: 9:16 gets tall
   fast, and a clip taller than the fold stops reading as an illustration. */
.reel-frame {
  position: relative; display: block; margin: 0 auto;
  width: 100%; max-width: min(340px, 78vw);
  padding: 0; border: 0; background: var(--figbox);
  aspect-ratio: 9 / 16; border-radius: 24px; overflow: hidden;
  isolation: isolate; cursor: pointer; -webkit-appearance: none; appearance: none;
  box-shadow: 0 26px 60px -34px rgba(10, 14, 22, 0.5);
}
@media (min-width: 1100px) { .reel-frame { max-width: 360px; } }
[data-theme='dark'] .reel-frame { box-shadow: 0 26px 60px -30px rgba(0, 0, 0, 0.85); }
.reel-frame video { display: block; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.reel-frame:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Hairline ring, drawn over the video so the card has an edge in light mode
   where the clip's own pale corners would otherwise dissolve into the page. */
.reel-frame::before {
  content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  border-radius: inherit; box-shadow: inset 0 0 0 1px var(--cell);
}
/* A soft scrim so the badge keeps contrast over any frame, without dimming
   the picture. Always slightly present, fuller on hover. */
.reel-frame::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 120px; z-index: 1;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0));
  opacity: 0.6; transition: opacity 0.25s ease; pointer-events: none;
}
.reel-frame:hover::after, .reel-frame:focus-visible::after { opacity: 1; }
/* State badge, not a separate control: it shows what a click will do.
   Every glyph occupies the same grid cell so exactly one is ever seen, and a
   missing rule can never stack them into a taller pill. */
.reel-sound {
  position: absolute; right: 14px; bottom: 14px; z-index: 2;
  display: grid; place-items: center;
  width: 36px; height: 36px; border-radius: 50%;
  background: rgba(0, 0, 0, 0.38);
  -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3), inset 0 0 0 0.5px rgba(255, 255, 255, 0.24);
  color: #fff; pointer-events: none;
  transition: background 0.2s ease, transform 0.2s cubic-bezier(0.2, 0, 0.2, 1);
}
.reel-frame:hover .reel-sound { background: rgba(0, 0, 0, 0.55); transform: scale(1.06); }
.reel-frame:active .reel-sound { transform: scale(0.95); }
.reel-sound svg { grid-area: 1 / 1; display: none; }
/* Exactly one of three states: paused wins, then audible, else muted. */
.reel-frame .i-off { display: block; }
.reel-frame[aria-pressed='true'] .i-off { display: none; }
.reel-frame[aria-pressed='true'] .i-on { display: block; }
.reel-frame[data-paused='true'] .i-off,
.reel-frame[data-paused='true'] .i-on { display: none; }
.reel-frame[data-paused='true'] .i-play { display: block; }
@media (prefers-reduced-motion: reduce) {
  .reel-sound, .reel-frame::after { transition: none; }
  .reel-frame:hover .reel-sound, .reel-frame:active .reel-sound { transform: none; }
}
.post-reel figcaption {
  margin-top: 20px; padding: 0 16px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; line-height: 1.8;
  color: var(--idx); text-wrap: balance;
}
/* The download is the one thing here worth tapping, so it gets a target
   rather than being a line of small caps among other small caps. */
.reel-cta {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 12px 22px;
  border: 1px solid var(--chip-border); border-radius: 999px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--accent); text-decoration: none;
  transition: border-color 0.18s ease, color 0.18s ease;
}
.reel-cta:hover { border-color: var(--accent); }
.reel-cta:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Reduced motion: the clip is handed to native controls rather than
   looping on its own, and the custom overlays step out of the way. */
.reel-frame video[controls] ~ .reel-link,
.reel-frame video[controls] ~ .reel-sound { display: none; }

/* ── Back to top ──────────────────────────────────────────────────
   The editorial pages load editorial-base + this file only, so the old
   .back-top rule in blog.css never applied and the link sat unstyled,
   hard against the last paragraph. Same quiet mono voice as .ba-back. */
.back-top {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 64px;
  font-family: var(--mono); font-size: 10.5px; font-weight: 400;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--idx); text-decoration: none;
  transition: color 0.18s ease;
}
.back-top::before { content: '\2191'; font-size: 12px; letter-spacing: 0; }
.back-top:hover { color: var(--accent); }
.back-top:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

/* ── Share (relocated to the end of the body) ─────────────────────── */
.post-share {
  margin-top: 76px; padding-top: 26px; border-top: 1px solid var(--cell);
  display: flex; align-items: center; gap: 10px;
}
.post-share::before {
  content: 'Share';
  margin-right: auto;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--idx);
}
.share-icon {
  display: grid; place-items: center;
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--chip-border); color: var(--ink3);
  transition: color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}
.share-icon:hover { color: var(--accent); border-color: var(--accent); opacity: 1; }
/* The hide rule must out-specify the display rule (the [hidden] lesson):
   the native-share button stays hidden where the browser has no share sheet. */
.share-icon[hidden] { display: none; }
/* Copy-link: the chain and checkmark glyphs swap via .copied (share.js). */
.share-icon .i-check { display: none; }
.share-icon.copied .i-link { display: none; }
.share-icon.copied .i-check { display: block; }
.share-icon.copied { color: var(--accent); border-color: var(--accent); }

/* ── Keep reading — full-bleed split ──────────────────────────────── */
.ba-next {
  margin-top: 110px;
  background: var(--block);
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
}
.ba-next-panel {
  min-height: 420px; padding: 76px 72px 72px; box-sizing: border-box;
  display: flex; flex-direction: column; justify-content: space-between; gap: 60px;
  color: inherit;
  border-left: 1px solid transparent;
  transition: background 0.18s ease;
}
.ba-next-panel + .ba-next-panel { border-left-color: rgba(16, 22, 36, 0.14); }
[data-theme='dark'] .ba-next-panel + .ba-next-panel { border-left-color: rgba(255, 255, 255, 0.14); }
.ba-next-panel:hover { background: rgba(16, 22, 36, 0.035); opacity: 1; }
[data-theme='dark'] .ba-next-panel:hover { background: rgba(255, 255, 255, 0.04); }
.ba-next-panel:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }
.ba-next-top { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; }
.ba-next-label, .ba-next-read, .ba-next-cat {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
}
.ba-next-label { color: var(--ink3); }
.ba-next-read { color: var(--idx); }
.ba-next-cat { display: block; color: var(--idx); }
.ba-next-title {
  display: block; margin-top: 16px; max-width: 20ch;
  font-size: clamp(30px, 3.4vw, 44px); font-weight: 200; letter-spacing: -0.042em; line-height: 1.04;
  color: var(--ink); text-wrap: pretty;
}
.ba-next-go {
  display: inline-flex; align-items: center; gap: 10px; margin-top: 28px;
  font-size: 16.5px; font-weight: 400; letter-spacing: -0.012em;
  color: var(--ink);
}

/* ── Back to top ──────────────────────────────────────────────────── */
.back-to-top {
  position: fixed; bottom: 24px; right: 24px; z-index: 60;
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--chip-border); background: var(--bg); color: var(--ink);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.14);
  opacity: 0; visibility: hidden; pointer-events: none; transform: translateY(8px);
  transition: opacity 0.2s, transform 0.2s, visibility 0.2s;
}
.back-to-top.show { opacity: 1; visibility: visible; pointer-events: auto; transform: none; }
.back-to-top svg { width: 18px; height: 18px; }

/* Split meets the footer directly. */
footer { margin-top: 0; }
/* The floating back-to-top circle shares the fine-print corner — keep the
   App Store badge clear of it (same clearance as the homepage). */

/* ── Responsive ───────────────────────────────────────────────────── */
@media (max-width: 1000px) {
  /* One column below 1000 — the two type columns would each be too narrow. */
  .ba-panel { grid-template-columns: minmax(0, 1fr); padding: 80px 40px 96px; }
  .ba-panel > .ba-cats, .ba-panel > h1, .ba-panel > .ba-stand { grid-column: 1; }
  .ba-panel > .ba-stand { grid-row: auto; align-self: start; margin: 26px 0 0; }
  .ba-panel > .ba-meta { grid-row: auto; }
  .ba-panel h1 { font-size: clamp(36px, 7vw, 44px); }
}
@media (max-width: 900px) {
  .ba-body { padding: 72px 22px 32px; }
  article.post { padding-left: 0; }
  article.post p { font-size: 19px; }
  article.post > p:first-of-type { font-size: 21px; }
  article.post h2 { font-size: clamp(27px, 6vw, 30px); margin-top: 56px; }
  article.post blockquote { font-size: clamp(24px, 6vw, 27px); margin: 44px 0; }
}
@media (max-width: 860px) {
  .ba-next { grid-template-columns: 1fr; }
  .ba-next-panel { min-height: 0; padding: 56px 40px; gap: 44px; border-left: 0; }
  .ba-next-panel + .ba-next-panel { border-left: 0; border-top: 1px solid rgba(16, 22, 36, 0.14); }
  [data-theme='dark'] .ba-next-panel + .ba-next-panel { border-top-color: rgba(255, 255, 255, 0.14); }
}
@media (max-width: 700px) {
  .ba-next-panel { padding: 48px 22px; }
  /* Photographs go full-bleed on a phone. The shelf mock and the reel are
     capped cards, so they stay in the column. */
  .post-figure, .post-hero {
    width: 100vw; margin-left: calc(50% - 50vw);
  }
  .post-figure img, .post-hero img { border-radius: 0; }
  .post-figure figcaption, .post-hero figcaption { padding: 0 22px; }
}
@media (prefers-reduced-motion: reduce) {
  .back-to-top { transition: opacity 0.2s, visibility 0.2s; }
  .ba-next-panel { transition: none; }
}

/* ── Visible byline ───────────────────────────────────────────────
   The author existed only in meta tags and JSON-LD, so no reader ever
   saw who wrote these. Structured data alone is a weak authorship
   signal; the name has to be on the page. Links to the founder block
   on /press, which is the same entity the Article schema references.
   Colour comes from .ba-meta a, which out-specifies anything set here, so
   the byline carries the same accent as the other link in the row. That is
   the right answer anyway: both are links and should read as links. */
.ba-author {
  text-decoration: none;
  border-bottom: 1px solid rgba(244, 98, 159, 0.4);
  padding-bottom: 2px;
  transition: border-color 0.18s ease;
}
.ba-author:hover { border-bottom-color: #f4629f; }
.ba-author:focus-visible { outline: 2px solid #f4629f; outline-offset: 3px; }

/* Where a post was first published. Moved out of the header, where it was
   costing a whole line on mobile, to the foot of the piece it belongs to. */
.post-source {
  margin: 44px 0 0;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; line-height: 1.9;
  color: var(--idx);
}
.post-source a { color: var(--accent); text-decoration: none; }
.post-source a:hover { opacity: 0.7; }

/* ── Author card ──────────────────────────────────────────────────
   The byline used to jump the reader across to /press#contact, which
   lands mid-page inside a media kit written for journalists. A reader
   clicking a byline wants to know who wrote this, so the answer now
   sits at the foot of the piece they just read and the byline is an
   in-page jump. The press kit is still one link away for press. */
.post-author {
  margin-top: 76px; padding-top: 30px; border-top: 1px solid var(--cell);
  display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: 26px;
  align-items: start; scroll-margin-top: 96px;
}
.pa-face { width: 112px; height: 112px; border-radius: 50%; object-fit: cover; background: var(--figbox); }
.pa-eyebrow {
  display: block;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--idx);
}
.pa-name { margin: 12px 0 0; font-size: 22px; font-weight: 400; letter-spacing: -0.022em; color: var(--ink); }
.pa-bio {
  margin: 10px 0 0; max-width: 56ch;
  font-size: 17px; font-weight: 300; line-height: 1.6; color: var(--prose); text-wrap: pretty;
}
.pa-links { display: flex; flex-wrap: wrap; gap: 8px 22px; margin: 16px 0 0; }
.pa-links a {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--accent); text-decoration: none;
}
.pa-links a:hover { opacity: 0.7; }
@media (max-width: 700px) {
  .post-author { grid-template-columns: 1fr; gap: 18px; }
  .pa-face { width: 88px; height: 88px; }
}
