/* Ontaym Blog — shared article stylesheet.
   Palette mirrors the in-app blog screens (lib/features/blog/presentation/
   screens/blog_list_screen.dart): white canvas, white cards separated by a
   hairline + soft elevation, turquoise brand accent.
   2026-09-09: rewritten to follow the app's monochrome-premium redesign --
   see the palette/alignment notes further down for what changed and why. */

:root {
  --bg: #ffffff;
  --card: #ffffff;
  --card2: #f6f7f8;
  --ink: #14191e;
  --ink-soft: #3a4551;
  --muted: #676a79;
  --brand: #24b1c7;
  --brand-deep: #1897ac;
  --tag-blue: #24b1c7;
  --tag-blue-bg: rgba(36, 177, 199, 0.10);
  --cta: #24b1c7;
  --cta-hover: #1897ac;
  --border: rgba(12, 20, 23, 0.10);
  --line: rgba(12, 20, 23, 0.10);
  --card-shadow: 0 2px 8px rgba(12, 20, 23, 0.05);
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  /* 2026-09-09: 17px -> 18px / 1.7. Prose now fills the card's full inner
     width (see the reading-measure note further down), and type this size
     keeps ~90-character lines comfortable -- 17px/1.65 at that measure
     read dense. 1.7 also matches the Dart article paragraphs (height: 1.7).
     ≤480px drops back to 16px in the small-screen block below. */
  font-size: 18px;
  line-height: 1.7;
}

/* Index list sits on the site's one 1080px rail (AppLayout.publicMaxWidth),
   same as the brand bar above it -- see the alignment note further down.
   Articles cap narrower (article.card, below): prose reads best well short
   of a 1080px line length, so the article's own column is capped there
   instead of on this shared wrapper. */
.wrap {
  max-width: 1080px;
  margin: 0 auto;
  padding: 24px 20px 64px;
}

/* ── Header ─────────────────────────────────────────────── */
.site-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 2px 18px;
}

.wordmark {
  font-weight: 800;
  font-size: 22px;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
}

.wordmark span { color: var(--brand); }

.site-head .home-link {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.55);
}

.site-head .home-link:hover { background: var(--cta); }

/* ── Breadcrumb ─────────────────────────────────────────── */
.crumb {
  font-size: 14px;
  color: var(--ink-soft);
  padding-bottom: 14px;
}

.crumb a { color: var(--ink-soft); text-decoration: none; }
.crumb a:hover { color: var(--ink); text-decoration: underline; }
.crumb .sep { margin: 0 6px; opacity: 0.6; }

/* ── Article card ───────────────────────────────────────── */
/* 2026-09-09: capped at its own reading measure (860px -- matches
   BlogPalette.postWidth in blog_list_screen.dart) rather than stretching to
   the full 1080px .wrap. Left-pinned (no auto margin), same as the Dart
   article route pins its inner rail to the outer rail's left edge instead
   of centring inside it -- see capToContentRail's alignment note. */
article.card {
  max-width: 860px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: clamp(24px, 5vw, 48px);
  box-shadow: var(--card-shadow);
}

h1 {
  font-size: clamp(28px, 5.4vw, 40px);
  line-height: 1.18;
  letter-spacing: -0.02em;
  margin: 8px 0 12px;
}

.post-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--ink-soft);
  margin-bottom: 24px;
}

.pill {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--tag-blue-bg);
  color: var(--tag-blue);
  font-weight: 700;
  font-size: 13px;
}

.lead {
  font-size: 20px;
  line-height: 1.6;
  color: var(--ink-soft);
  border-left: 4px solid var(--brand);
  padding-left: 16px;
  margin: 0 0 12px;
}

/* ── Hero figure ────────────────────────────────────────── */
figure.hero { margin: 26px 0 8px; }

figure.hero img {
  width: 100%;
  height: auto;
  border-radius: 14px;
  display: block;
}

figcaption {
  font-size: 13.5px;
  color: var(--ink-soft);
  margin-top: 8px;
}

/* ── Body typography ────────────────────────────────────── */
h2 {
  font-size: clamp(22px, 3.6vw, 28px);
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 44px 0 14px;
}

h3 {
  font-size: 19px;
  margin: 30px 0 10px;
}

p { margin: 0 0 18px; }

ul, ol { padding-left: 24px; margin: 0 0 18px; }
li { margin-bottom: 8px; }

li::marker { color: var(--brand); font-weight: 700; }

a { color: var(--tag-blue); }

strong { font-weight: 700; }

blockquote {
  margin: 22px 0;
  padding: 14px 18px;
  background: rgba(44, 171, 201, 0.10);
  border-left: 4px solid var(--brand);
  border-radius: 0 12px 12px 0;
  color: var(--ink);
}

blockquote p { margin: 0; }

/* ── Quick answer / takeaways callouts ──────────────────── */
/* 2026-09-09: was `background: #ffffff` -- a deliberate white panel INSIDE
   article.card back when the card itself was cream. Now that the card is
   white too, a white panel on a white card has no edge at all beyond its
   border; --card2 (the app's own step-down surface, AppColors.card2) keeps
   it a visibly separate box. Every other "boxed" element below
   (.toc/.sources/.authorbox/.related/figure.ctx/table-wrap) had the same
   white-on-white problem and gets the same fix. */
.callout {
  background: var(--card2);
  border: 1.5px solid rgba(36, 177, 199, 0.35);
  border-radius: 16px;
  padding: 18px 22px;
  margin: 26px 0;
}

.callout h2, .callout h3 { margin-top: 0; }

/* ── Tables ─────────────────────────────────────────────── */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 26px 0;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--card2);
}

table {
  border-collapse: collapse;
  width: 100%;
  min-width: 520px;
  font-size: 15px;
}

caption {
  caption-side: top;
  text-align: left;
  font-weight: 700;
  padding: 12px 14px 4px;
  color: var(--ink);
}

th, td {
  text-align: left;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

th {
  background: rgba(44, 171, 201, 0.12);
  font-size: 13.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink);
}

tbody tr:last-child td { border-bottom: none; }

/* Was rgba(251, 243, 225, 0.55) -- the old --cream, hardcoded here instead
   of tokenized, so the --sky/--cream removal above missed it. A neutral
   ink-tinted zebra stripe now, matching --card2. */
tbody tr:nth-child(even) { background: rgba(12, 20, 23, 0.03); }

/* ── Steps ──────────────────────────────────────────────── */
ol.steps { counter-reset: step; list-style: none; padding-left: 0; }

ol.steps > li {
  counter-increment: step;
  position: relative;
  padding-left: 52px;
  margin-bottom: 18px;
}

ol.steps > li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 1px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  font-weight: 800;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
}

ol.steps > li::marker { content: none; }

/* ── FAQ ────────────────────────────────────────────────── */
.faq h3 {
  font-size: 17px;
  margin-bottom: 6px;
}

.faq p { margin-bottom: 20px; }

/* ── Contextual figures ─────────────────────────────────── */
figure.ctx { margin: 28px 0; }

figure.ctx img, figure.ctx svg {
  width: 100%;
  height: auto;
  border-radius: 14px;
  display: block;
  background: var(--card2);
}

/* ── Related reading & footer CTA ──────────────────────── */
.related {
  background: var(--card2);
  border-radius: 16px;
  padding: 20px 24px;
  margin-top: 40px;
}

.related h2 { margin-top: 0; font-size: 20px; }

.related ul { margin-bottom: 0; }

.cta-box {
  margin-top: 26px;
  padding: 22px 24px;
  border-radius: 16px;
  background: var(--ink);
  color: #f4efe2;
}

.cta-box p { margin: 0 0 14px; color: #a9aeb6; font-size: 15px; }

.cta-box a {
  display: inline-block;
  background: var(--cta);
  /* White, not var(--ink): matches AppColors.onPrimary -- every filled
     button on an accent-teal background reads white-on-brand app-wide,
     never dark ink on it (dark text here is a leftover from --cta being
     pale sky-blue; on the saturated brand teal it read as noticeably
     lower-contrast than the rest of the product's buttons). */
  color: #ffffff;
  font-weight: 800;
  text-decoration: none;
  padding: 12px 22px;
  border-radius: 12px;
}

.cta-box a:hover { background: var(--cta-hover); }

footer.site-foot {
  margin-top: 34px;
  font-size: 14px;
  color: var(--ink-soft);
}

footer.site-foot a { color: var(--ink-soft); }

/* ── Small screens ──────────────────────────────────────── */
@media (max-width: 480px) {
  body { font-size: 16px; }
  .lead { font-size: 18px; }
  .wrap { padding: 16px 14px 48px; }
  article.card { border-radius: 16px; }
}


/* ══════════════════════════════════════════════════════════════════════
   2026-08-22 -- alignment pass. Superseded 2026-09-09, see below.

   THE INDEX LIST. `/blog` had no static index.html at all, so the route
   fell through to the Flutter SPA and listed the single post that lives in
   Dart while 87 published articles sat unlinked. The styles below are that
   index.

   ── 2026-09-09: THE PHANTOM SIDEBAR IS GONE ─────────────────────────────
   This block used to reserve 280px of dead left padding on `body` above
   1024px (plus a negative margin pulling the brand bar back out of it), on
   the theory that these pages should sit where they'd land if the app's
   docked sidebar were drawn beside them. That sidebar doesn't exist any
   more on any route -- the app shell is top-striped now, not side-docked
   (see AdaptiveNavigationShell / BlogPageRail's own "no longer mounted"
   note in blog_list_screen.dart) -- so the gutter these pages were
   aligning to was reserving space for a column that had already been
   removed everywhere else. `.wrap` and `.brand-bar-inner` both simply
   centre on the shared 1080px rail now, same as every other public page.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Brand bar ──────────────────────────────────────────── */
.brand-bar {
  background: var(--card);
  border-bottom: 1px solid var(--border);
}

.brand-bar-inner {
  max-width: 1080px;
  margin: 0 auto;
  padding: 18px 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.brand-mark {
  display: block;
  line-height: 0;
  border-radius: 6px;
}

.brand-mark img { display: block; width: 34px; height: 34px; }

.brand-bar .home-link {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(20, 22, 26, 0.05);
}

.brand-bar .home-link:hover { background: var(--cta); color: var(--ink); }

@media (max-width: 1023px) { .brand-bar-inner { padding: 18px 32px; } }
@media (max-width: 767px) { .brand-bar-inner { padding: 14px 20px; } }

/* ── Index page ─────────────────────────────────────────── */
.page-head { padding: 8px 2px 20px; }

.page-head h1 {
  font-size: clamp(30px, 5vw, 42px);
  margin: 0 0 8px;
}

.page-head p { margin: 0; color: var(--ink-soft); font-size: 17px; }

.post-list {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 20px;
  overflow: hidden;
  box-shadow: var(--card-shadow);
}

.post-row {
  display: flex;
  gap: 16px;
  align-items: center;
  padding: 20px;
  text-decoration: none;
  color: inherit;
  border-bottom: 1px solid var(--line);
}

.post-row:last-child { border-bottom: 0; }
.post-row:hover { background: rgba(20, 22, 26, 0.04); }

/* 2026-09-09: the 500%-zoom-into-an-OG-card trick this comment used to
   describe only ever made sense against the old sky/cream artwork it was
   zooming into -- with that palette gone the cropped corner had nothing
   coherent left to show. Posts with a real photo set their own inline
   background-image on the row (unaffected by this rule); this is now
   purely the flat, neutral fallback for the couple of posts that don't --
   the same [AppColors.card2] tile the Dart placeholder
   (_BlogThumbnail) uses when a post has no cover image, rather than a
   colored gradient standing in for a missing picture. */
.post-row .thumb {
  flex: 0 0 auto;
  width: 84px;
  height: 84px;
  border-radius: 12px;
  background: var(--card2);
  border: 1px solid var(--border);
}

.post-row .body { min-width: 0; }

.post-row h2 {
  font-size: 19px;
  line-height: 1.3;
  margin: 8px 0;
  letter-spacing: -0.01em;
}

.post-row .row-meta { font-size: 13px; color: var(--ink-soft); margin: 0; }

/* The pill is a link child here, so it must not inherit the row's
   text-decoration reset as a colour change on hover. */
.post-row .pill { font-size: 12px; padding: 3px 10px; }

@media (max-width: 600px) {
  .post-row { gap: 12px; padding: 16px; }
  .post-row .thumb { width: 64px; height: 64px; }
  .post-row h2 { font-size: 17px; }
}


/* ══════════════════════════════════════════════════════════════════════
   2026-08-22 — ARTICLE TEMPLATE v2.

   The rewrite pass moved the articles from "a wall of prose in a cream
   card" to a structured document: a jump-to index, an extractable
   takeaways block, inline definitions, a sources list and an author
   footer. Everything below is additive — v1 pages keep rendering
   unchanged, because none of these class names existed before.

   Two rules governed the choices:

   * MEASURE. Body copy is capped at 68ch. The card can grow with the
     viewport; the line length may not. Long lines are the single biggest
     readability regression on a 920px card at desktop width.

   * NO LAYOUT SHIFT. Nothing here animates, loads a font, or needs
     JavaScript. Every figure carries width/height, so CLS stays at zero
     and the TOC is a plain <nav> of anchors a crawler can follow.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Reading measure ────────────────────────────────────── */
/* 2026-09-09: the 68ch cap this block used to put on text-level children
   is GONE. It gave prose (~620px) a different width than everything else
   in the card -- figures, tables, callouts and the h2 hairlines kept the
   full inner width -- so every paragraph stopped ~140px short of the
   media's right edge and all the slack piled up on one side. Three
   different right edges (lead / body / image) read as a layout bug, not
   as typographic discipline -- reported as the post "not using the box
   well". Text now shares ONE edge with the media on both sides, which is
   also how the Dart article screen (blog_post_screen.dart) already
   renders: its paragraphs were never capped. Comfort at the wider
   measure is carried by the type (18px / 1.7 at the top of this file),
   not by re-narrowing the column. */

article.card > p { margin: 0 0 20px; }

/* Section headings get a hairline above them so the eye finds the seam
   without needing a bigger type jump. */
article.card > h2 {
  padding-top: 6px;
  border-top: 1px solid var(--line);
  margin-top: 48px;
}

article.card > h2:first-of-type { border-top: 0; }

/* ── Table of contents ──────────────────────────────────── */
.toc {
  background: var(--card2);
  border: 1.5px solid rgba(36, 177, 199, 0.35);
  border-radius: 16px;
  padding: 18px 22px;
  margin: 28px 0;
}

.toc h2 {
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  margin: 0 0 10px;
  border-top: 0;
  padding-top: 0;
}

.toc ol {
  margin: 0;
  padding-left: 20px;
  columns: 2;
  column-gap: 28px;
}

.toc li {
  margin-bottom: 7px;
  break-inside: avoid;
  font-size: 15.5px;
}

.toc a { text-decoration: none; }
.toc a:hover { text-decoration: underline; }

@media (max-width: 640px) {
  .toc ol { columns: 1; }
}

/* ── Key takeaways ──────────────────────────────────────── */
.takeaways {
  background: rgba(44, 171, 201, 0.09);
  border-left: 4px solid var(--brand);
  border-radius: 0 16px 16px 0;
  padding: 18px 22px;
  margin: 28px 0;
}

.takeaways h2 {
  font-size: 18px;
  margin: 0 0 10px;
  border-top: 0;
  padding-top: 0;
}

.takeaways ul { margin: 0; padding-left: 22px; }
.takeaways li { margin-bottom: 10px; }
.takeaways li:last-child { margin-bottom: 0; }

/* ── Inline definitions ─────────────────────────────────── */
/* A <dl> of terms the article relies on. Kept visible on the page
   because the structured data may only describe what a reader can see. */
.deflist {
  margin: 26px 0;
  padding: 4px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.deflist dt {
  font-weight: 800;
  margin-top: 16px;
  color: var(--ink);
}

.deflist dd {
  margin: 4px 0 0;
  color: var(--ink-soft);
}

.deflist dd:last-child { margin-bottom: 16px; }

/* ── Pull quote ─────────────────────────────────────────── */
.pull {
  margin: 30px 0;
  padding: 0 0 0 22px;
  border-left: 5px solid var(--brand);
  font-size: clamp(19px, 2.6vw, 22px);
  line-height: 1.42;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  /* 2026-09-09: was max-width: 60ch -- same one-sided-slack problem the
     68ch body cap had (see the reading-measure note). A pull quote is a
     display element; it spans the column like every other block now. */
}

/* ── Tables: scroll affordance ──────────────────────────── */
/* The wrapper already scrolls; the fade tells a phone reader that it
   does. Pure CSS, no listener, so it costs nothing on INP.
   2026-09-09: this rule comes after (and wins over) the plain --card2
   background above, so it's the one that actually paints -- the fades
   must resolve to the SAME --card2, not #fff, or the "faded edge" reads as
   a visible white seam against the card2 base it sits on. */
.table-wrap {
  background:
    linear-gradient(to right, var(--card2) 30%, rgba(246,247,248,0)) left / 40px 100% no-repeat,
    linear-gradient(to left, var(--card2) 30%, rgba(246,247,248,0)) right / 40px 100% no-repeat,
    radial-gradient(farthest-side at 0 50%, rgba(12,20,23,0.14), transparent) left / 14px 100% no-repeat,
    radial-gradient(farthest-side at 100% 50%, rgba(12,20,23,0.14), transparent) right / 14px 100% no-repeat,
    var(--card2);
  background-attachment: local, local, scroll, scroll, local;
}

caption { padding: 14px 14px 8px; line-height: 1.4; }

/* ── Sources ────────────────────────────────────────────── */
.sources {
  margin: 40px 0 0;
  padding: 20px 24px;
  background: var(--card2);
  border-radius: 16px;
  font-size: 15px;
}

.sources h2 {
  font-size: 17px;
  margin: 0 0 10px;
  border-top: 0;
  padding-top: 0;
}

.sources ol { margin: 0; padding-left: 20px; }
.sources li { margin-bottom: 8px; color: var(--ink-soft); }

/* ── Author box ─────────────────────────────────────────── */
.authorbox {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  margin-top: 36px;
  padding: 20px 24px;
  background: var(--card2);
  border-radius: 16px;
}

.authorbox img {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: block;
}

.authorbox .who { font-weight: 800; margin: 0 0 4px; }

.authorbox p {
  margin: 0;
  font-size: 14.5px;
  color: var(--ink-soft);
  line-height: 1.55;
}

/* ── Related reading with descriptions ──────────────────── */
.related ul { list-style: none; padding-left: 0; }

.related li {
  margin-bottom: 14px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}

.related li:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: 0; }

.related a { font-weight: 700; text-decoration: none; }
.related a:hover { text-decoration: underline; }

.related .blurb {
  display: block;
  font-size: 14.5px;
  color: var(--ink-soft);
  margin-top: 3px;
  line-height: 1.5;
}

/* ── Figures: give diagrams room to breathe ─────────────── */
figure.ctx img { border: 1px solid var(--line); }

figure.hero img { border: 1px solid rgba(20, 22, 26, 0.08); }

/* ── FAQ ────────────────────────────────────────────────── */
.faq h3 {
  font-size: 17.5px;
  margin-top: 22px;
  margin-bottom: 6px;
}

.faq h3:first-child { margin-top: 4px; }

/* ── Small screens ──────────────────────────────────────── */
@media (max-width: 480px) {
  article.card > h2 { margin-top: 38px; }
  .toc, .takeaways, .sources, .related, .authorbox { padding: 16px 18px; }
  .authorbox { gap: 12px; }
  .pull { font-size: 18px; padding-left: 16px; }
}

/* ══════════════════════════════════════════════════════════════════════
   2026-08-22 -- index thumbnails.

   The rows used to show a 500% zoom into the decorative corner of each
   post's generated OG card, because the card's left half is the headline
   and any honest crop rendered it as mush. That trick is retired: every
   post now has a real photograph, cropped square at source, so the tile
   can simply show the picture.

   The <picture> element is the flex child, and the <img> fills it. Width
   and height are on the img so the row reserves its space before the
   file arrives, which keeps CLS at zero on a cold load.
   ══════════════════════════════════════════════════════════════════════ */

.post-row picture.thumb {
  display: block;
  flex: 0 0 auto;
  width: 84px;
  height: 84px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--card2);
  border: 1px solid var(--border);
}

.post-row picture.thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 600px) {
  .post-row picture.thumb { width: 64px; height: 64px; }
}


/* A stray diagram must never break the page. Article images are capped at
   the column regardless of whether they were wrapped in a <figure>. */
article.card img { max-width: 100%; height: auto; }
article.card > img { display: block; margin: 28px 0; border-radius: 14px;
  border: 1px solid var(--line); background: #fff; }
