/* rotascale.com — the layout grammar.
 *
 * subhadipmitra@: Rules, alignment and tabular figures. No card borders, no
 * shadow, no radius except where a control genuinely needs one.
 *
 * The reason is not taste. The page is arguing that this product produces
 * records a stranger can check, and a record is set as ruled columns with
 * figures that line up — not as a soft-cornered tile floating over a
 * background. Every visual decision below is downstream of that.
 */

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.56;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg { max-width: 100%; height: auto; }

/* subhadipmitra@: The browser default is a blue-grey that belongs to no design
   system on this page. Selection is one of the few surfaces a reader creates
   themselves, and it should look like the site did it. Tinted from the accent
   rather than set to it — a full-strength magenta wash makes the text under it
   harder to read, and the point of selecting text is to read it. */
/* subhadipmitra@: `background-color`, not the `background` shorthand, and no
   `color` at all.
   The first version set `background: …; color: …` and on some browsers only the
   colour landed — so selecting text changed the letters and painted nothing
   behind them, which reads as the text darkening rather than as a highlight.
   The shorthand is the unreliable half here. Leaving `color` unset also means
   the highlight cannot make text less readable than it was, which is the one
   thing a selection style must never do. */
::selection { background-color: var(--select); }
::-moz-selection { background-color: var(--select); }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }

/* Anything that can scroll sideways does so inside its own box. The page body
   never does. */
.scroll-x { overflow-x: auto; }
/* A scrolling block is a box; give it the space a box needs below it. */
.scroll-x + .note, .scroll-x + .limit { margin-top: 30px; }
.defs + .note, .defs + .limit, .claims + .note, .claims + .limit { margin-top: 30px; }

a { color: inherit; }

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

.skip {
  position: absolute; left: -9999px;
  background: var(--ink); color: var(--on-ink);
  padding: 10px 16px; z-index: 100;
}
.skip:focus { left: var(--gutter); top: 10px; }

/* --- type ---------------------------------------------------------------- */

h1, h2, h3 { text-wrap: balance; }

h1 {
  font-family: var(--serif);
  font-size: clamp(40px, 5.9vw, 72px);
  line-height: 1.03;
  font-weight: 600;
  letter-spacing: -0.021em;
  margin: 0 0 24px;
  max-width: 17ch;
}
h1 em { font-style: italic; font-weight: 500; color: var(--accent); }

h2 {
  font-family: var(--serif);
  font-size: clamp(27px, 3.3vw, 38px);
  line-height: 1.12;
  font-weight: 600;
  letter-spacing: -0.017em;
  margin: 0 0 16px;
  max-width: 21ch;
}

h3 { font-size: 15.5px; font-weight: 600; margin: 0; letter-spacing: -0.004em; }

.lead {
  font-size: 18.5px;
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 58ch;
  margin: 0;
}
.lead b, .lead strong { font-weight: 600; color: var(--ink); }

.kicker {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 24px;
}
.kicker b { color: var(--accent); font-weight: 500; }

.note { font-size: 13.5px; color: var(--muted); margin: 26px 0 0; max-width: 66ch; }

/* --- the claim mark ------------------------------------------------------
 *
 * The organising idea of this site: every claim carries the product's own
 * three-state discipline. `observed` links to the thing itself — the running
 * demo, the published specification, the source. `asserted` says plainly that
 * there is nothing here a reader can check from outside.
 *
 * It costs us something, which is exactly why it is worth having. A page that
 * marks its own unverifiable claims is not a device a competitor copies.
 */

.mark {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  padding: 2px 6px;
  white-space: nowrap;
  border: 1px solid currentColor;
  display: inline-block;
}
.mark--observed { color: var(--allow); }
.mark--asserted { color: var(--muted); }
a.mark { text-decoration: none; }
a.mark:hover { background: var(--allow); color: var(--paper); border-color: var(--allow); }

/* --- masthead ------------------------------------------------------------ */

.mast { border-bottom: 1px solid var(--rule-hard); }
/* subhadipmitra@: `>` matters. The panel reuses `.wrap` for its own gutter, so
   a descendant selector here reached inside it and applied `display:flex;
   align-items:center` to the panel's grid — which centred the columns and
   dropped the shorter one by half the height difference. Second time a
   contextual class rule has quietly reformatted a component on this site; the
   fix both times is to stop the ancestor rule travelling. */
.mast > .wrap { display: flex; align-items: center; gap: 18px; padding-top: 13px; padding-bottom: 11px; }

.brand { display: flex; align-items: center; gap: 9px; text-decoration: none; }
.brand img { height: 20px; width: auto; display: block; }
.brand .word { font-size: 17px; font-weight: 700; letter-spacing: -0.012em; align-self: baseline; }
.brand .desc { font-size: 12.5px; font-weight: 400; color: var(--muted); white-space: nowrap; }
/* subhadipmitra@: The descriptor is the first thing to go. Five menu buttons
   plus a call to action need the room more than a subtitle does, and a masthead
   that wraps to two lines looks broken in a way a missing tagline does not. */
@media (max-width: 1220px) { .brand .desc { display: none; } }

/* The mark ships in two cuts; each hides in the other's theme. */
.brand .m-dark { display: none; }
:root[data-theme="dark"] .brand .m-light { display: none; }
:root[data-theme="dark"] .brand .m-dark { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brand .m-light { display: none; }
  :root:not([data-theme="light"]) .brand .m-dark { display: block; }
}

/* --- the menu -----------------------------------------------------------
 *
 * subhadipmitra@: A ruled panel, not a card. Columns divided by hairlines, mono
 * labels, no icons, no shadow, no radius — because a mega menu that looked like
 * every other one would quietly undo the argument the rest of the page is
 * making about what this product's surfaces look like.
 */

.mast { position: relative; }
.mast__nav { margin-left: auto; display: flex; gap: 2px; flex-shrink: 0; }

.navitem { position: static; }

.navitem__btn {
  display: inline-flex; align-items: center; gap: 6px;
  font: 400 14px/1 var(--sans); color: var(--ink-2);
  background: none; border: 0; padding: 8px 10px; cursor: pointer;
}
.navitem__btn svg { transition: transform 120ms ease; opacity: .55; }
.navitem__btn[aria-expanded="true"] { color: var(--ink); }
.navitem__btn[aria-expanded="true"] svg { transform: rotate(180deg); opacity: 1; }
.navitem__btn:hover { color: var(--ink); }
.navitem__btn[data-current="true"] { color: var(--ink); box-shadow: inset 0 -1px 0 var(--ink); }
@media (prefers-reduced-motion: reduce) { .navitem__btn svg { transition: none; } }

/* Full-bleed under the masthead: the panel belongs to the rule above it. */
.panel {
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--paper);
  border-bottom: 1px solid var(--rule-hard);
  z-index: 40;
}
.panel[hidden] { display: none; }

.panel__grid {
  display: grid;
  /* subhadipmitra@: A bounded track, not `1fr`. With `auto-fit` and a fraction
     the browser made six tracks for three columns of links and the panel
     emptied into the right half of the page. Columns are 200–250px and pack
     left, so two groups and five groups both look deliberate. */
  grid-template-columns: repeat(auto-fit, minmax(200px, 250px));
  justify-content: start; align-items: start;
  gap: 0; padding-top: 26px; padding-bottom: 30px;
}
.panel__col { padding-right: 28px; border-right: 1px solid var(--rule); }
.panel__col:last-child { border-right: 0; padding-right: 0; }
.panel__col + .panel__col { padding-left: 28px; }

.panel__label {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 12px;
}
.panel ul, .mobilenav ul { list-style: none; margin: 0; padding: 0; }
.panel li { margin-bottom: 2px; }
.panel a {
  display: block; text-decoration: none; padding: 7px 0; font-size: 14.5px;
  border-bottom: 1px solid transparent;
}
.panel a:hover { color: var(--accent); }
.panel a[aria-current="page"] { color: var(--ink); font-weight: 600; }
.panel__note {
  display: block; font-size: 12.5px; color: var(--muted); margin-top: 2px;
  max-width: 30ch;
}

/* --- mobile -------------------------------------------------------------- */

.mast__burger {
  display: none; background: none; border: 1px solid var(--rule);
  color: var(--ink-2); width: 32px; height: 32px; cursor: pointer;
  place-items: center;
}
.mobilenav {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 40;
  background: var(--paper); border-bottom: 1px solid var(--rule-hard);
  max-height: 78vh; overflow-y: auto;
}
.mobilenav[hidden] { display: none; }
.mobilenav__group { padding: 20px 0 4px; border-bottom: 1px solid var(--rule); }
.mobilenav a { display: block; text-decoration: none; padding: 9px 0; font-size: 15.5px; }
.mobilenav a[aria-current="page"] { font-weight: 600; }

.mast .cta {
  font-size: 13.5px; font-weight: 500; padding: 9px 15px; white-space: nowrap;
  background: var(--ink); color: var(--on-ink); text-decoration: none; flex-shrink: 0;
}
.mast .cta:hover { background: var(--accent); color: #fff; }

.theme-toggle {
  background: none; border: 1px solid var(--rule); color: var(--muted);
  width: 32px; height: 32px; cursor: pointer; display: grid; place-items: center;
  font-family: inherit;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--ink); }

/* --- buttons ------------------------------------------------------------- */

.btn {
  display: inline-block;
  font: 500 14.5px/1 var(--sans);
  padding: 13px 19px;
  text-decoration: none;
  background: var(--ink);
  color: var(--on-ink);
  border: 1px solid var(--ink);
  cursor: pointer;
}
.btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn--ghost { background: none; color: var(--ink); }

.acts { display: flex; gap: 12px; margin: 32px 0 0; align-items: center; flex-wrap: wrap; }

/* --- the record ----------------------------------------------------------
 * Set as a ruled document because it IS one. A card would make it a
 * screenshot of a UI, which is a weaker claim.
 */

.record { margin: 54px 0 0; border-top: 1px solid var(--rule-hard); }

.record__head {
  display: flex; align-items: baseline; gap: 13px; flex-wrap: wrap;
  padding: 13px 0 11px; border-bottom: 1px solid var(--rule);
  font-family: var(--mono); font-size: 12.5px;
}
.record__head .who { color: var(--muted); }
.record__state {
  margin-left: auto; font-size: 10.5px; letter-spacing: 0.09em;
  text-transform: uppercase; padding: 2px 8px; border: 1px solid currentColor;
}
.record__state--deny { color: var(--deny); }
.record__state--allow { color: var(--allow); }
.record__state--review { color: var(--review); }

.rows { display: grid; grid-template-columns: 1fr 1fr; }
.rows > div { padding: 14px 0; border-bottom: 1px solid var(--rule); }
.rows > div:nth-child(odd) { padding-right: 30px; border-right: 1px solid var(--rule); }
.rows > div:nth-child(even) { padding-left: 30px; }

.k {
  font-size: 11.5px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 4px;
}
.v { font-family: var(--mono); font-size: 14px; }
.v--deny { color: var(--deny); font-weight: 500; }

/* --- the gate rail -------------------------------------------------------
 * Nine gates in a FIXED order is the one structural fact no competitor's
 * diagram has, so it is drawn as a sequence that visibly stops rather than as
 * nine equal boxes.
 */

.rail { padding: 20px 0 0; }
.rail__k {
  font-size: 11.5px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 11px;
}
.rail__track { display: grid; grid-template-columns: repeat(9, 1fr); gap: 3px; }
.rail__track span { height: 6px; background: var(--allow); }
.rail__track span.is-stop { background: var(--deny); }
.rail__track span.is-off { background: var(--rule); }
.rail__names {
  display: grid; grid-template-columns: repeat(9, 1fr); gap: 3px; margin-top: 9px;
  font-family: var(--mono); font-size: 10.5px; color: var(--muted);
  letter-spacing: -0.01em; word-break: break-word; line-height: 1.3;
}
.rail__names b { color: var(--deny); font-weight: 600; }
.rail__names i { font-style: normal; opacity: 0.45; }

.hero { padding: 86px 0 76px; }
.hero .lead { margin-top: 4px; }

/* --- sections and claim lists -------------------------------------------- */

.sec { padding: 72px 0; border-top: 1px solid var(--rule); }
/* subhadipmitra@: `:not()` because this rule was silently winning against the
   utility classes. `.sec > .wrap > p` scores 0,2,1 and `.note` scores 0,1,0, so
   a `.note` or `.limit` sitting directly in a section lost its top margin and
   collided with whatever was above it — visible after a `.defs` list and after
   a `.scroll-x` table. A section-level type selector fighting a component class
   over spacing is the classic way a stylesheet develops mystery gaps. */
.sec > .wrap > p:not(.note):not(.limit):not(.lead):not(.legend) {
  font-size: 17px; color: var(--ink-2); max-width: 63ch; margin: 0;
}

.claims { margin: 36px 0 0; border-top: 1px solid var(--rule-hard); }
.claim {
  display: grid; grid-template-columns: 230px 1fr 108px; gap: 32px;
  align-items: start; padding: 19px 0; border-bottom: 1px solid var(--rule);
}
.claim p { font-size: 14.8px; color: var(--ink-2); margin: 0; max-width: 60ch; }

.legend { margin: 30px 0 0; font-size: 13.5px; color: var(--muted); max-width: 66ch; }
.legend .mark { margin-right: 5px; }

/* --- footer -------------------------------------------------------------- */

.foot { border-top: 1px solid var(--rule-hard); padding: 54px 0 40px; margin-top: 20px; }
.foot__grid { display: grid; grid-template-columns: 1.4fr repeat(4, 1fr); gap: 32px; }
.foot h4 {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 12px; font-weight: 500;
}
.foot ul { list-style: none; margin: 0; padding: 0; font-size: 14px; }
.foot li { margin-bottom: 7px; }
.foot a { color: var(--ink-2); text-decoration: none; }
.foot a:hover { color: var(--ink); box-shadow: inset 0 -1px 0 var(--ink); }
.foot__legal {
  display: flex; gap: 20px; flex-wrap: wrap; align-items: baseline;
  margin-top: 40px; padding-top: 18px; border-top: 1px solid var(--rule);
  font-size: 13px; color: var(--muted);
}
.foot__legal .spacer { margin-left: auto; }

@media (max-width: 900px) {
  :root { --gutter: 20px; }
  .rows { grid-template-columns: 1fr; }
  .rows > div:nth-child(odd) { border-right: 0; padding-right: 0; }
  .rows > div:nth-child(even) { padding-left: 0; }
  .claim { grid-template-columns: 1fr; gap: 8px; }
  .foot__grid { grid-template-columns: 1fr 1fr; }
  .rail__names { font-size: 8px; }
  .mast__nav, .mast .cta, .brand .desc { display: none; }
  .mast__burger { display: grid; }
}

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


/* --- components the platform pages need ---------------------------------- */

/* A code sample. Ruled top and bottom rather than boxed, same as a record. */
.code {
  font-family: var(--mono); font-size: 13px; line-height: 1.7;
  background: var(--paper-2); padding: 18px 20px; margin: 26px 0 0;
  overflow-x: auto; border-left: 2px solid var(--rule-hard);
}
.code .c { color: var(--muted); }
.code .s { color: var(--accent); }

/* The gate table: nine rows, in order, with what each one asks. */
.gates { width: 100%; border-collapse: collapse; margin: 34px 0 0; }
.gates th {
  text-align: left; font-size: 11.5px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); padding: 0 0 10px;
  border-bottom: 1px solid var(--rule-hard);
}
.gates td { padding: 14px 0; border-bottom: 1px solid var(--rule); vertical-align: top; font-size: 14.5px; }
.gates td:first-child { font-family: var(--mono); font-size: 13px; color: var(--muted); width: 56px; }
.gates td:nth-child(2) { font-family: var(--mono); font-size: 13.5px; width: 168px; }
.gates td:nth-child(2) b { font-weight: 500; }
.gates td:last-child { color: var(--ink-2); }

/* The enforcement ladder: four rungs, and only two of them refuse. */
.ladder { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; margin: 32px 0 0;
  background: var(--rule); border-top: 1px solid var(--rule-hard); }
.ladder > div { background: var(--paper); padding: 18px 20px 20px; }
.ladder h4 { font-family: var(--mono); font-size: 12.5px; font-weight: 500; margin: 0 0 8px; }
.ladder p { font-size: 13.5px; color: var(--ink-2); margin: 0; }
.ladder .is-enforcing h4 { color: var(--allow); }
.ladder .is-watching h4 { color: var(--review); }
.ladder__note { font-size: 13.5px; color: var(--muted); margin: 14px 0 0; }

/* Two-column definition rows: term on the left, what it means on the right. */
.defs { margin: 32px 0 0; border-top: 1px solid var(--rule-hard); }
.def { display: grid; grid-template-columns: 230px 1fr; gap: 32px; padding: 18px 0;
  border-bottom: 1px solid var(--rule); }
.def dt { font-weight: 600; font-size: 15px; }
.def dd { margin: 0; font-size: 14.8px; color: var(--ink-2); max-width: 64ch; }
.def dd code, .def dt code { font-family: var(--mono); font-size: 13px; }

/* A comparison: what this is not. */
.compare { width: 100%; border-collapse: collapse; margin: 32px 0 0; }
.compare th { text-align: left; font-size: 11.5px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); padding: 0 16px 10px 0;
  border-bottom: 1px solid var(--rule-hard); }
.compare td { padding: 15px 16px 15px 0; border-bottom: 1px solid var(--rule);
  vertical-align: top; font-size: 14.5px; color: var(--ink-2); }
.compare td:first-child { color: var(--ink); font-weight: 500; width: 24%; }

/* A stated limit. Used where the honest answer is "we do not do that". */
.limit { border-left: 2px solid var(--review); padding: 6px 0 6px 20px;
  margin: 34px 0 0; font-size: 15px; color: var(--ink-2); max-width: 64ch; }
.limit b { color: var(--ink); }

/* Page navigation between siblings. */
.siblings { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1px; background: var(--rule); border-top: 1px solid var(--rule-hard);
  margin: 0; }
.siblings a { background: var(--paper); padding: 18px 20px; text-decoration: none; display: block; }
.siblings a:hover { background: var(--paper-2); }
.siblings .k { margin-bottom: 5px; }
.siblings span { font-size: 15px; font-weight: 600; }

@media (max-width: 900px) {
  .ladder { grid-template-columns: 1fr; }
  .def { grid-template-columns: 1fr; gap: 6px; }
  .gates td:nth-child(2) { width: auto; }
}


/* --- the verifier -------------------------------------------------------- */

.vinput {
  width: 100%; font-family: var(--mono); font-size: 13px; line-height: 1.6;
  background: var(--paper-2); color: var(--ink);
  border: 1px solid var(--rule); border-left: 2px solid var(--rule-hard);
  padding: 14px 16px; margin-top: 8px; resize: vertical;
}
.vinput::placeholder { color: var(--muted); }

.vout:not(:empty) { margin: 30px 0 0; border-top: 1px solid var(--rule-hard); }
.vrow { display: grid; grid-template-columns: 92px 1fr; gap: 20px; align-items: start;
  padding: 16px 0; border-bottom: 1px solid var(--rule); }
.vrow b { font-size: 15px; font-weight: 600; }
.vdetail { font-size: 14px; color: var(--ink-2); margin-top: 5px; max-width: 62ch; }
.vdetail code { font-family: var(--mono); font-size: 12px; word-break: break-all; }
.vstate { font-family: var(--mono); font-size: 10px; letter-spacing: 0.09em;
  text-transform: uppercase; padding: 2px 6px; border: 1px solid currentColor;
  display: inline-block; }
.vstate--passed { color: var(--allow); }
.vstate--failed { color: var(--deny); }
.vstate--unknown { color: var(--review); }

@media (max-width: 900px) { .vrow { grid-template-columns: 1fr; gap: 8px; } }


/* --- long-form ------------------------------------------------------------
 *
 * subhadipmitra@: Twenty-five posts were rendering with no prose styles at all,
 * because the stylesheet was rebuilt around the marketing pages and `.prose`
 * never came with it. They were readable only in the sense that a browser
 * default is readable.
 *
 * Measure first: the posts use h2/h3 heavily, fenced code, tables and long
 * lists, so those are what this has to get right. Body copy sits at 65-ish
 * characters, which is where reading stops being work.
 */

.prose { max-width: 68ch; font-size: 17px; line-height: 1.68; }
.prose > * + * { margin-top: 1.1em; }

.prose h2 {
  font-family: var(--serif); font-size: 28px; line-height: 1.2; font-weight: 600;
  letter-spacing: -0.015em; margin: 2em 0 0; max-width: 24ch;
  padding-top: 0.7em; border-top: 1px solid var(--rule);
}
.prose h3 {
  font-size: 18px; font-weight: 600; letter-spacing: -0.005em; margin: 1.8em 0 0;
}
.prose h4 { font-size: 15.5px; font-weight: 600; margin: 1.5em 0 0; color: var(--ink-2); }

.prose p { margin: 0; }
.prose a { color: var(--ink); box-shadow: inset 0 -1px 0 var(--rule-hard); text-decoration: none; }
.prose a:hover { color: var(--accent); box-shadow: inset 0 -1px 0 var(--accent); }

.prose ul, .prose ol { margin: 1.1em 0 0; padding-left: 1.3em; }
.prose li { margin-bottom: 0.45em; }
.prose li > ul, .prose li > ol { margin-top: 0.45em; }

.prose blockquote {
  margin: 1.6em 0 0; padding: 2px 0 2px 20px; border-left: 2px solid var(--accent);
  color: var(--ink-2);
}
.prose blockquote p + p { margin-top: 0.8em; }

.prose code {
  font-family: var(--mono); font-size: 0.86em;
  background: var(--paper-2); padding: 1px 5px;
}
.prose pre {
  font-family: var(--mono); font-size: 13px; line-height: 1.7;
  background: var(--paper-2); border-left: 2px solid var(--rule-hard);
  padding: 16px 18px; overflow-x: auto; margin: 1.5em 0 0;
}
.prose pre code { background: none; padding: 0; font-size: inherit; }

/* A table in a post is data; it gets the same rules the rest of the site uses. */
.prose table { width: 100%; border-collapse: collapse; margin: 1.6em 0 0; font-size: 15px; }
.prose th {
  text-align: left; font-size: 11.5px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); padding: 0 14px 9px 0;
  border-bottom: 1px solid var(--rule-hard);
}
.prose td { padding: 12px 14px 12px 0; border-bottom: 1px solid var(--rule); vertical-align: top; }

.prose hr { border: 0; border-top: 1px solid var(--rule); margin: 2.4em 0 0; }
.prose img { display: block; margin: 1.6em 0 0; }
.prose strong { font-weight: 600; }

/* --- post listing --------------------------------------------------------- */

.posts { margin: 40px 0 0; border-top: 1px solid var(--rule-hard); list-style: none; padding: 0; }
.posts li { border-bottom: 1px solid var(--rule); }
.posts a { display: grid; grid-template-columns: 118px 1fr; gap: 28px;
  padding: 20px 0; text-decoration: none; align-items: baseline; }
.posts a:hover h3 { color: var(--accent); }
.posts time { font-family: var(--mono); font-size: 12.5px; color: var(--muted); }
.posts h3 { font-size: 17px; font-weight: 600; margin: 0 0 5px; max-width: 46ch; }
.posts p { font-size: 14.5px; color: var(--ink-2); margin: 0; max-width: 62ch; }

.postmeta {
  font-family: var(--mono); font-size: 12px; color: var(--muted);
  letter-spacing: 0.03em; margin: 0 0 30px;
}

@media (max-width: 900px) {
  .prose { font-size: 16.5px; }
  .posts a { grid-template-columns: 1fr; gap: 6px; }
}

/* A rendered diagram is a figure, not a code block. */
.prose .mermaid { margin: 1.8em 0 0; text-align: center; overflow-x: auto; }
.prose .mermaid svg { max-width: 100%; height: auto; }
