/* ============================================================
   Monoleaf site, shared stylesheet

   Palette rule, in two halves:

   1. CHROME is ink on paper, and gold #E8A33D is its only accent.
      The surface and ink values are the Monoleaf application's own
      light-mode tokens, so the site and the app a visitor is about
      to install look like one product. Do not add a second accent.

   2. DOCUMENT COLOURS. Insertion green, deletion red and comment blue
      appear only inside a document preview, never as chrome. They
      are what a tracked change looks like, not what the site looks
      like. The one place they would tempt you is the portability
      verdicts, and there we use ink / gold / grey instead.

   Gold is a fill and a rule colour, not a text colour: #E8A33D on
   paper is 1.9:1. Use --gold-ink for any accent that is read.
   ============================================================ */
:root{
  /* surfaces, taken from the application's light mode verbatim */
  --paper:#F6F6F4;                /* app --bg        */
  --panel:#FBFBFA;                /* app --panel: chrome bars  */
  --raised:#FFFFFF;               /* app --editor-bg: canvas and cards */
  --slab:#23252A;                 /* brand ink: dark sections, raw panes */
  --slab-2:#2B2E34;               /* a card sitting on the slab */
  --slab-rule:#383B42;            /* app --border, dark */

  /* ink */
  --ink:#20201E;                  /* app --text  */
  --ink-2:#55544F;
  --ink-3:#6F6E69;                /* app --muted */
  --rule:#E4E3DF;                 /* app --border */
  --rule-soft:#EDECE8;

  /* cream, for type on the slab */
  --cream:#F5F1E8;                /* brand on-dark  13.6:1 */
  --cream-2:#B4B1A8;              /*                 7.1:1 */
  --cream-3:#98958B;              /*                 5.1:1 */

  /* the one accent */
  --gold:#E8A33D;                 /* brand gold: fills, rules, marks */
  --gold-ink:#8A5A11;             /* 5.5:1 on paper: accent text, focus, badges */
  --gold-soft:rgba(232,163,61,.14);

  /* document colours, previews only. See the rule above. */
  --ins:#1B7A50; --del:#A23B37; --note:#3E6DA8;

  --display:"Newsreader", ui-serif, Georgia, serif;
  --body:"Archivo", ui-sans-serif, system-ui, sans-serif;
  --mono:"IBM Plex Mono", ui-monospace, "SFMono-Regular", monospace;

  --max:1120px;
  --pad:clamp(18px, 5vw, 48px);
  --nav-h:58px;
  --tap:44px;                     /* minimum touch target */
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth}
body{
  margin:0; background:var(--paper); color:var(--ink);
  font-family:var(--body); font-size:16.5px; line-height:1.62;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  overflow-x:hidden;              /* belt and braces on narrow phones */
}
img{max-width:100%; display:block}
a{color:inherit}
:focus-visible{outline:2px solid var(--gold-ink); outline-offset:3px; border-radius:2px}

/* Anchored sections must clear the sticky nav */
section,header[id]{scroll-margin-top:calc(var(--nav-h) + 12px)}

.eyebrow{
  font-family:var(--mono); font-size:11.5px; font-weight:500;
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink-3);
  margin:0 0 18px;
}
h1,h2,h3{font-family:var(--display); font-weight:400; letter-spacing:-.011em; margin:0}
h1{font-size:clamp(2.2rem,7.4vw,4.5rem); line-height:1.04; letter-spacing:-.026em}
h2{font-size:clamp(1.65rem,4.4vw,2.75rem); line-height:1.14; letter-spacing:-.018em}
h3{font-size:1.14rem; line-height:1.35; font-weight:500}

.wrap{
  max-width:var(--max); margin:0 auto;
  /* Longhands on purpose. The `padding` shorthand would also set top and
     bottom to 0, and `.wrap` (0,1,0) outranks `section` (0,0,1), so every
     section.wrap would silently lose its vertical rhythm. */
  padding-left:max(var(--pad), env(safe-area-inset-left));
  padding-right:max(var(--pad), env(safe-area-inset-right));
}
section{padding:clamp(48px,9vw,116px) 0}
.rule-top{border-top:1px solid var(--rule)}
.lede{font-size:clamp(1.02rem,1.7vw,1.24rem); color:var(--ink-2); max-width:62ch; margin:0}
.mono{font-family:var(--mono)}
code{font-family:var(--mono); font-size:.9em}

/* ---------------- nav, with a real mobile menu ---------------- */
.nav{
  position:sticky; top:0; z-index:60;
  background:color-mix(in srgb, var(--paper) 90%, transparent);
  backdrop-filter:blur(10px); border-bottom:1px solid var(--rule);
}
.nav-in{
  max-width:var(--max); margin:0 auto; padding:0 var(--pad);
  min-height:var(--nav-h); display:flex; align-items:center; gap:24px;
}
/* The brand lockup is the real logo, inlined rather than <img>-loaded:
   Chromium rasterises an <img> SVG to an intermediate bitmap and then
   rescales it for DPI, which leaves hairline seams in the wordmark on
   a 125% display. Inline, it composites at device resolution. This is
   the same fix the application's title bar uses. */
.brand{display:flex; align-items:center; text-decoration:none; margin-right:auto}
.brand-logo{display:block; height:22px; width:auto}
.nav-links{display:flex; gap:24px}
.nav-links a{
  font-family:var(--mono); font-size:12.5px; color:var(--ink-2); text-decoration:none;
  padding:4px 0; border-bottom:1px solid transparent; transition:border-color .18s,color .18s;
}
.nav-links a:hover{color:var(--ink); border-bottom-color:var(--ink)}
/* 2px, because a 1px gold hairline is too quiet to read as "you are here". */
.nav-links a[aria-current="page"]{
  color:var(--ink); border-bottom:2px solid var(--gold); padding-bottom:3px;
}

.nav-toggle{
  display:none; font-family:var(--mono); font-size:12px; letter-spacing:.06em;
  text-transform:uppercase; background:none; border:1px solid var(--rule);
  border-radius:3px; color:var(--ink); cursor:pointer;
  min-height:var(--tap); padding:0 14px;
}
@media(max-width:820px){
  .nav-toggle{display:inline-flex; align-items:center}
  .brand{min-height:var(--tap); align-items:center}
  .nav-links{
    position:absolute; top:100%; left:0; right:0;
    flex-direction:column; gap:0; background:var(--paper);
    border-bottom:1px solid var(--rule); padding:6px 0 10px;
    box-shadow:0 12px 24px -18px rgba(0,0,0,.35);
  }
  .nav-links[hidden]{display:none}
  .nav-links a{
    padding:0 var(--pad); min-height:var(--tap); display:flex; align-items:center;
    border-bottom:1px solid var(--rule-soft); font-size:14px;
  }
  .nav-links a:last-child{border-bottom:0}
  .nav-links a:hover{border-bottom-color:var(--rule-soft)}
}

/* ---------------- buttons ---------------- */
.btn{
  font-family:var(--mono); font-size:13px; font-weight:500;
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  min-height:var(--tap); padding:12px 20px; border-radius:3px;
  text-decoration:none; cursor:pointer;
  border:1px solid var(--ink); background:var(--ink); color:var(--paper);
  transition:background .18s,color .18s,border-color .18s;
}
.btn:hover{background:#000}
.btn-ghost{background:transparent; color:var(--ink); border-color:var(--rule)}
.btn-ghost:hover{background:transparent; border-color:var(--ink)}
.btn-sub{font-family:var(--mono); font-size:11.5px; color:var(--ink-3)}
.badge{
  display:inline-block; vertical-align:middle;
  font-family:var(--mono); font-size:10.5px; font-weight:600;
  letter-spacing:.06em; text-transform:uppercase; line-height:1;
  color:var(--gold-ink); background:var(--gold-soft);
  border:1px solid var(--gold); border-radius:3px; padding:4px 6px;
}
@media(max-width:520px){
  .btn{width:100%}
  .btn-sub{width:100%; text-align:center}
}

/* ---------------- hero ---------------- */
.hero{padding-top:clamp(40px,8vw,96px); padding-bottom:clamp(32px,5vw,60px)}
.hero h1{max-width:19ch}
.hero h1 em{font-style:italic; color:var(--gold-ink)}
.hero .lede{margin-top:22px}
.hero-actions{display:flex; flex-wrap:wrap; gap:12px; align-items:center; margin-top:30px}

/* ============================================================
   SIGNATURE: one file, three readers
   ============================================================ */
.demo{border:1px solid var(--rule); border-radius:5px; background:var(--raised); overflow:hidden}

/* The panel stays inside the text column: no full-bleed breakout. The Monoleaf
   view fits by being scaled down instead. See .ml-win. */
.demo-bar{display:flex; align-items:stretch; border-bottom:1px solid var(--rule); background:var(--panel)}
.demo-file{
  display:flex; align-items:center; gap:8px; padding:0 16px; min-height:46px;
  font-family:var(--mono); font-size:12px; color:var(--ink-3);
  border-right:1px solid var(--rule); white-space:nowrap; overflow:hidden;
}
.demo-file b{color:var(--ink-2); font-weight:500; text-overflow:ellipsis; overflow:hidden}
.tabs{display:flex; margin-left:auto}
.tab{
  font-family:var(--mono); font-size:12px; letter-spacing:.03em;
  background:none; border:0; border-left:1px solid var(--rule);
  padding:0 16px; min-height:46px; cursor:pointer; color:var(--ink-3);
  position:relative; transition:color .18s,background .18s;
}
.tab:hover{color:var(--ink); background:var(--paper)}
/* Selected state is carried by THREE things, not just the gold bar: the label
   goes from --ink-3 to --ink (4.7:1 to 15:1) and gains weight, and aria-selected
   states it outright. That redundancy is deliberate. The gold bar alone measures
   2.08:1 against the panel, under the 3:1 that WCAG 1.4.11 asks of a non-text
   indicator, so it must not be the only signal. Darkening it to --gold-ink would
   pass in isolation but turns the brand accent muddy for no real gain. */
.tab[aria-selected="true"]{color:var(--ink); background:var(--raised); font-weight:600}
.tab[aria-selected="true"]::after{content:""; position:absolute; inset:0 0 auto; height:2px; background:var(--gold)}
.panel{display:none}
.panel.is-on{display:block; animation:fade .3s ease}
@keyframes fade{from{opacity:0}to{opacity:1}}
.demo-foot{
  border-top:1px solid var(--rule); padding:12px 16px; background:var(--panel);
  font-family:var(--mono); font-size:11.5px; color:var(--ink-3); line-height:1.6;
}

/* Phone: file name on its own row, tabs as a full-width 3-up grid */
@media(max-width:700px){
  .demo-bar{flex-direction:column}
  .demo-file{border-right:0; border-bottom:1px solid var(--rule); min-height:40px; font-size:11.5px}
  .tabs{margin-left:0; display:grid; grid-template-columns:repeat(3,1fr)}
  .tab{border-left:0; border-right:1px solid var(--rule); min-height:var(--tap); padding:0 6px; font-size:11.5px}
  .tab:last-child{border-right:0}
}
/* "Another reader" is the longest label and sets the floor. At 360px it fits
   with a hair to spare; below that it needs the extra room. */
@media(max-width:380px){
  .tab{font-size:10.5px; padding:0 3px; letter-spacing:0}
}

.raw{
  background:var(--slab); color:var(--cream-2); margin:0;
  padding:24px 18px; overflow-x:auto; -webkit-overflow-scrolling:touch;
  font-family:var(--mono); font-size:13px; line-height:1.85; tab-size:2;
}
@media(max-width:700px){.raw{font-size:11.5px; line-height:1.8; padding:18px 14px}}
.raw .c-syn{color:var(--cream-3)}
.raw .c-head{color:var(--cream); font-weight:600}
.raw .c-ins{color:#5BC98E}
.raw .c-del{color:#E0847F}
.raw .c-cmt{color:#7FA8D9}
.raw .c-ml{color:#9C8FD1}
.raw .c-str{color:#D9C275}

/* A browser-based renderer fills its container but still caps the body:
   GitHub stops around 1012px. Without this, the wider demo panel would give
   the other-reader view a 1400px measure that no real reader produces. */
.doc{padding:clamp(20px,4vw,44px); font-size:15.5px; max-width:1000px; margin:0 auto}

/* Monoleaf lays out on a page, not on a browser-width column: the editor pins
   .cm-content to 794px (A4 at 96dpi) and centres it. Without this the preview
   runs the full width of the panel, prose gets an uncomfortable measure, and a
   three-column table stretches far wider than the app would ever draw it.
   704px is 794 less the page's own side padding.
   The other-reader panel deliberately does NOT get this, because a browser-based
   renderer really does fill its container, and that difference is real. */
.doc.is-page{max-width:704px; margin:0 auto}
/* Sans, not the site's Newsreader: Monoleaf sets the document face to
   "Segoe UI Variable" and sizes h1 at 1.7em. A serif heading here would be the
   website's typography wearing the application's clothes. */
.doc .d-h1{font-family:var(--body); font-size:1.7em; font-weight:600;
  margin:0 0 2px; letter-spacing:-.015em; line-height:1.25}
.doc .d-h2{font-family:var(--body); font-size:1.28em; font-weight:600;
  margin:26px 0 2px; letter-spacing:-.008em; line-height:1.3}
.doc p{margin:14px 0}
.doc .d-math{font-family:var(--display); font-style:italic; font-size:1.05rem;
  text-align:center; padding:16px 0; overflow-x:auto}
.frac{display:inline-flex; flex-direction:column; vertical-align:middle;
  text-align:center; margin:0 3px; font-size:.85em}
.frac span:first-child{border-bottom:1px solid currentColor; padding:0 4px}
.frac span:last-child{padding:0 4px}

/* A table inside the document previews.
   These values are `.ml-table` from the application's src/styles.css, copied
   rather than invented: a fully gridded table with a shaded header, not the
   borderless rules-only table a design system would reach for by default. The
   preview has to show what Monoleaf actually draws.
   The global `thead th` rule is mono, small and uppercase because it dresses
   UI tables; it must not reach a table inside a document. */
.d-tbl{border-collapse:collapse; width:100%; font-size:0.95em; margin:14px 0}
.d-tbl th, .d-tbl td{
  border:1px solid #C9C8C4;        /* app: light-dark(#c9c8c4, #4a4a46) */
  padding:6px 10px; min-width:48px; vertical-align:top;
}
.d-tbl thead th{
  font-family:var(--body); font-size:1em; font-weight:600; letter-spacing:0;
  text-transform:none; color:var(--ink);
  background:#F3F3F1;              /* app: light-dark(#f3f3f1, #2b2b2a) */
  text-align:left;
}
/* GFM column alignment is honoured. tablewidget.ts sets textAlign on both the
   header and body cells from the delimiter row, so `---:` right-aligns both. */
.d-tbl .num{text-align:right; font-variant-numeric:tabular-nums}

/* The callout as an ordinary blockquote, which is what a reader without
   GitHub-flavoured alerts actually shows. */
.d-quote{
  margin:18px 0; padding:2px 0 2px 16px; border-left:3px solid var(--rule);
  color:var(--ink-2);
}
.d-quote p{margin:0}

.fnref{font-size:.72em; color:var(--note); padding-left:1px}
.fn{
  margin-top:20px; padding-top:12px; border-top:1px solid var(--rule-soft);
  font-size:13px; color:var(--ink-2);
}
.fn sup{color:var(--note); padding-right:3px}

.callout{border-left:3px solid var(--note); background:#F4F7FB;
  padding:12px 16px; margin:18px 0; border-radius:0 3px 3px 0}
.callout-h{font-family:var(--mono); font-size:11px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--note); font-weight:600; margin-bottom:3px}
.callout p{margin:0}
.callout-gh{border-left:3px solid #1F6FEB; background:transparent; padding:2px 0 2px 16px}
.callout-gh .callout-h{color:#1F6FEB}

/* Tracked changes and the comment anchor, copied from .cm-critic-ins,
   .cm-critic-del and .cm-comment-range in the application's src/styles.css.
   The anchor is an AMBER highlight, not a blue underline. That was invented. */
.t-ins{
  color:#1A7A2E; background:rgba(40,170,70,.09);
  text-decoration:underline; text-decoration-color:rgba(26,122,46,.45);
  text-underline-offset:2px;
}
.t-del{
  color:#B02A2A; background:rgba(200,50,50,.08);
  text-decoration:line-through; text-decoration-color:rgba(176,42,42,.55);
}
.t-anchor{background:rgba(255,200,40,.26); border-radius:2px}
.lit{font-family:var(--mono); font-size:.9em; color:var(--ink-2);
  background:var(--paper); padding:1px 3px; border-radius:2px; word-break:break-all}

/* ============================================================
   MONOLEAF APPLICATION CHROME AROUND THE PREVIEW

   The outline on the left and the comment panel on the right are the two
   places a comment body and a heading list actually live. Inline comment
   bubbles under the paragraph were an invention and are gone. Widths and
   metrics are #outline-sidebar (250px) and #comments-sidebar (320px) from
   the application's src/styles.css.
   ============================================================ */
/* Scaled down rather than re-proportioned.

   All three panes keep the application's real numbers (250px outline, 320px
   comment panel, 12.5px outline items, a 704px page) and the whole window is
   then displayed at 85%, which is what looking at the app on a smaller screen
   actually does. Re-tuning each width to fit would have silently replaced every
   value copied out of src/styles.css with a website-shaped approximation, and
   the next person comparing the two would have found nothing matching.

   `zoom` is used rather than `transform: scale()` because it participates in
   layout, so the panel still sizes its own height and nothing overlaps. Where
   it is unsupported the row simply falls back to shrinking the page column,
   which is cramped but not broken. */
.ml-win{zoom:0.85}
@media(max-width:1023px){ .ml-win{zoom:1} }

.ml-app{display:flex; align-items:stretch}

.ml-outline{
  width:250px; flex:none; background:var(--panel);
  border-right:1px solid var(--rule); padding:12px 6px;
}
.ml-outline-h{
  font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.05em;
  color:var(--ink-3); padding:2px 8px 8px;
}
.ml-outline-list{display:flex; flex-direction:column}
.ml-outline-item{
  display:block; width:100%; text-align:left; border:0; background:transparent;
  font-family:var(--body); font-size:12.5px; color:var(--ink);
  padding:5px 8px 5px 10px; border-radius:6px; cursor:default;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* Indent is 10px + 14px per heading level, as outline.ts computes it. */
.ml-outline-item.lvl2{padding-left:24px}
/* The app paints the active item `color: var(--accent)` on `--accent-soft`,
   which is 1.9:1 and unreadable. Same identity here, but with --gold-ink so the
   label can actually be read. Worth fixing upstream as well. */
.ml-outline-item.is-active{
  background:var(--gold-soft); color:var(--gold-ink); font-weight:600;
}

.ml-comments{
  width:320px; flex:none; background:var(--panel);
  border-left:1px solid var(--rule); padding:12px;
}
.ml-sb-head{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  margin-bottom:12px; padding-bottom:10px; border-bottom:1px solid var(--rule);
  font-size:12.5px; font-weight:600;
}
.ml-sb-head span{font-weight:400; font-size:12px; color:var(--ink-3)}

/* .comment-card in the application: a warm cream card, not a blue-ruled box. */
.c-card{
  border:1px solid #E8DDB8; background:#FFFDF2; border-radius:8px;
  padding:10px 12px; margin-bottom:10px; font-size:13px; line-height:1.55;
  box-shadow:0 1px 2px rgba(0,0,0,.04);
}
.c-card .c-meta{font-size:11px; color:var(--ink-3); margin-bottom:2px}
.c-card p{margin:0}

/* The status bar carries page setup, which is applied rather than printed
   into the document body. The old dashed "A4 · 20 mm margins" line under
   the text was not something the application ever shows. */
.ml-status{
  display:flex; justify-content:space-between; gap:12px; flex-wrap:wrap;
  border-top:1px solid var(--rule); background:var(--panel);
  padding:7px 14px; font-family:var(--mono); font-size:11px; color:var(--ink-3);
}

/* Both panels are toggleable in the application, so hiding the outline and
   dropping comments below the page is what a narrow window really looks like.
   The breakpoint matches .ml-win's: below it there is no room for three panes
   even scaled, so the layout stacks instead of shrinking further. */
@media(max-width:1023px){
  .ml-app{display:block}
  .ml-outline{display:none}
  .ml-comments{width:auto; border-left:0; border-top:1px solid var(--rule)}
}

/* ---------------- feature grid ---------------- */
.grid{display:grid; gap:1px; background:var(--rule); border:1px solid var(--rule);
  border-radius:4px; overflow:hidden; margin-top:40px}
@media(min-width:720px){.grid{grid-template-columns:1fr 1fr}}
@media(min-width:1000px){.grid{grid-template-columns:repeat(3,1fr)}}
.cell{background:var(--raised); padding:24px 22px 26px}
.cell h3{margin-bottom:8px}
.cell p{margin:0; color:var(--ink-2); font-size:15px}
.cell .k{font-family:var(--mono); font-size:11px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-3); display:block; margin-bottom:14px}

/* ---------------- spec strip ----------------
   The long tail of real features, in the mono "chrome" voice rather than
   as nine more cells. Anything here that grows an argument earns a cell. */
.spec{margin-top:30px; border-top:1px solid var(--rule); padding-top:22px}
.spec-h{
  font-family:var(--mono); font-size:11px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-3); margin:0 0 14px;
}
.spec ul{
  list-style:none; margin:0; padding:0; display:grid; gap:7px 28px;
  grid-template-columns:repeat(auto-fill, minmax(248px, 1fr));
}
.spec li{
  font-family:var(--mono); font-size:12.5px; line-height:1.55; color:var(--ink-2);
  padding-left:16px; position:relative;
}
.spec li::before{content:"·"; position:absolute; left:4px; color:var(--gold)}
.spec code{font-size:.95em}

/* ---------------- in the app ----------------
   Quiet frame on purpose: 1px rule, small radius, no drop shadow, no browser
   chrome mockup, no tilted perspective. The screenshot has to look like the
   application, not like an advertisement for it. */
.shot{margin:38px 0 0}
.shot-frame{
  border:1px solid var(--rule); border-radius:5px; overflow:hidden; background:var(--raised);
}
.shot img{width:100%; height:auto; display:block}

/* On a phone, a 2360px-wide window scaled to 350px is a silhouette: you can
   see there is a toolbar but not read it. Scroll it inside its own frame
   instead of shrinking it into uselessness. The raw pane and the portability
   table already behave this way, so the gesture is not a new one here. */
@media(max-width:680px){
  .shot-frame{overflow-x:auto; -webkit-overflow-scrolling:touch}
  .shot img{min-width:560px}
}
.shot figcaption{
  font-family:var(--mono); font-size:11.5px; color:var(--ink-3);
  margin-top:12px; line-height:1.7;
}

/* ---------------- why md ---------------- */
.why{background:var(--slab); color:var(--cream-2)}
.why h2{color:var(--cream)}
.why .eyebrow{color:var(--cream-3)}
.why .lede{color:var(--cream-2)}
.why code{color:var(--gold); background:var(--gold-soft); padding:1px 4px; border-radius:2px}
.why-list{list-style:none; padding:0; margin:44px 0 0; display:grid; gap:1px;
  background:var(--slab-rule); border:1px solid var(--slab-rule); border-radius:4px; overflow:hidden}
@media(min-width:820px){
  .why-list{grid-template-columns:1fr 1fr}
  /* With a 1px gap showing the rule colour through, an odd item count would
     leave a visible empty cell. Let a lone last item span the row instead. */
  .why-list li:last-child:nth-child(odd){grid-column:1 / -1}
}
.why-list li{background:var(--slab-2); padding:22px 22px 24px}
.why-list h3{color:var(--cream); margin-bottom:7px}
.why-list p{margin:0; color:#9B9A94; font-size:15px}

/* Method note for the one quantified claim on the site. Mono, because it is a
   footnote about how a number was arrived at rather than part of the argument. */
.why-note{
  font-family:var(--mono); font-size:11.5px; line-height:1.75;
  color:var(--cream-3); margin:24px 0 0; max-width:78ch;
}
.why-note code{background:none; color:var(--gold); padding:0}

/* ============================================================
   TABLES: scroll on tablet, stack into cards on phones
   ============================================================ */
.tbl-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch; margin-top:38px;
  border:1px solid var(--rule); border-radius:4px; background:var(--raised)}
table{border-collapse:collapse; width:100%; font-size:14.5px}
thead th{
  font-family:var(--mono); font-size:11px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-3); font-weight:500; text-align:left;
  padding:14px 18px; border-bottom:1px solid var(--rule); white-space:nowrap;
}
tbody td{padding:13px 18px; border-bottom:1px solid var(--rule-soft); vertical-align:top}
tbody tr:last-child td{border-bottom:0}
/* Verdicts are ink / gold / grey, not a traffic light. Green here would
   be the insertion colour doing chrome duty, and gold is better used
   pointing at the caveats, which is what this table is for. */
.yes{color:var(--ink)}
.part{color:var(--gold-ink)}
.no{color:var(--ink-3)}
.cst{font-family:var(--mono); font-size:13px; word-break:break-word}
.cst small{display:block; font-family:var(--body); font-size:12.5px; color:var(--ink-3); margin-top:2px}
.tbl-note{font-family:var(--mono); font-size:11.5px; color:var(--ink-3); margin:14px 0 0; line-height:1.7}
/* Named constructs inside a note, so the three kinds of leak are scannable
   without turning the paragraph into another list. */
.tbl-note b{color:var(--ink-2); font-weight:500}

/* portability table: 4 columns */
.t-port{min-width:640px}
.t-port thead th:not(:first-child){text-align:center; width:16%}
.t-port tbody td:not(:first-child){text-align:center; font-family:var(--mono); font-size:12.5px}

@media(max-width:680px){
  .tbl-scroll{border:0; background:transparent; overflow:visible}
  .t-port{min-width:0; display:block}
  .t-port thead{display:none}
  .t-port tbody,.t-port tr,.t-port td{display:block; width:100%}
  .t-port tr{
    background:var(--raised); border:1px solid var(--rule);
    border-radius:4px; margin-bottom:10px; padding:14px 16px;
  }
  .t-port tbody td{border:0; padding:0}
  .t-port tbody td:first-child{margin-bottom:10px}
  /* the three verdicts become labelled rows */
  .t-port tbody td:not(:first-child){
    display:flex; justify-content:space-between; align-items:baseline; gap:12px;
    text-align:left; padding:5px 0; border-top:1px solid var(--rule-soft);
    font-family:var(--mono); font-size:12px;
  }
  .t-port tbody td:not(:first-child)::before{
    content:attr(data-label); font-family:var(--mono); font-size:10.5px;
    letter-spacing:.09em; text-transform:uppercase; color:var(--ink-3);
  }
}

/* ---------------- downloads ---------------- */
.dl-head{display:flex; flex-wrap:wrap; gap:16px; align-items:flex-end; justify-content:space-between}
.rel-meta{font-family:var(--mono); font-size:12px; color:var(--ink-3); text-align:right}
@media(max-width:640px){.rel-meta{text-align:left}}
.rel-meta b{color:var(--ink); font-weight:500}
.dl-grid{display:grid; gap:1px; background:var(--rule); border:1px solid var(--rule);
  border-radius:4px; overflow:hidden; margin-top:32px}
@media(min-width:760px){.dl-grid{grid-template-columns:repeat(3,1fr)}}
.dl-os{background:var(--raised); padding:22px}
.dl-os h3{font-family:var(--mono); font-size:12px; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-3); margin-bottom:14px}
.dl-os.is-you h3{color:var(--gold-ink)}
.dl-list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:9px}
.dl-list a{
  display:flex; justify-content:space-between; align-items:center; gap:12px;
  font-family:var(--mono); font-size:12.5px; text-decoration:none; color:var(--ink);
  border:1px solid var(--rule); border-radius:3px; padding:10px 12px;
  min-height:var(--tap); transition:border-color .18s,background .18s;
}
.dl-list a:hover{border-color:var(--ink); background:var(--paper)}
.dl-list .sz{color:var(--ink-3); font-size:11.5px; white-space:nowrap}
.dl-empty{font-family:var(--mono); font-size:12px; color:var(--ink-3)}

/* Install realities. Stated here rather than discovered at first run. */
.dl-notes{margin-top:26px; display:grid; gap:12px; max-width:66ch}
.dl-notes p{margin:0; font-size:14px; color:var(--ink-2); line-height:1.65}
.dl-notes b{
  display:block; font-family:var(--mono); font-size:11px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--gold-ink); margin-bottom:3px;
}
.dl-notes em{font-style:normal; font-family:var(--mono); font-size:.92em; color:var(--ink)}

/* ============================================================
   LICENSES PAGE
   ============================================================ */
/* Longhands, for the same reason .wrap uses them. The three-value shorthand set
   padding-left and padding-right to 0, and .lic-hero is declared after .wrap at
   equal specificity (0,1,0), so it won and silently removed the horizontal
   padding every other block on the page has. The h1 and lede sat flush against
   the viewport edge while the nav, footer and following sections indented
   correctly, on all six pages that use this class and on 404.html. */
.lic-hero{padding-top:clamp(40px,7vw,72px); padding-bottom:clamp(24px,4vw,36px)}
.lic-stats{
  display:flex; flex-wrap:wrap; gap:1px; background:var(--rule);
  border:1px solid var(--rule); border-radius:4px; overflow:hidden; margin-top:32px;
}
.lic-stat{background:var(--raised); padding:16px 20px; flex:1 1 150px}
.lic-stat b{display:block; font-family:var(--display); font-size:1.9rem; line-height:1.1; font-weight:400}
.lic-stat span{font-family:var(--mono); font-size:10.5px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-3)}

.banner{
  border:1px solid var(--gold); border-left:3px solid var(--gold); border-radius:0 4px 4px 0;
  background:var(--gold-soft); padding:14px 18px; margin-top:28px;
}
.banner p{margin:0; font-size:14.5px; color:var(--ink-2)}
.banner b{font-family:var(--mono); font-size:11px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--gold-ink); display:block; margin-bottom:4px}

/* The renderer emits <section class="lic-group">, which would otherwise also
   pick up the global section padding and space the generated groups twice as
   far apart as the hand-written ones on this page. Margin is the only spacing. */
.lic-group{margin-top:clamp(36px,5vw,56px); padding:0}
.lic-group-h{
  display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;
  padding-bottom:10px; border-bottom:1px solid var(--rule); margin-bottom:0;
}
.lic-group-h h2{font-size:clamp(1.25rem,3vw,1.6rem)}
.lic-group-h .spdx{
  font-family:var(--mono); font-size:11px; letter-spacing:.08em; color:var(--gold-ink);
  border:1px solid var(--gold); border-radius:2px; padding:2px 7px;
}
.lic-group-h .cnt{font-family:var(--mono); font-size:11.5px; color:var(--ink-3); margin-left:auto}

.pkg-list{list-style:none; margin:0; padding:0}
.pkg{
  display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;
  padding:12px 2px; border-bottom:1px solid var(--rule-soft);
}
.pkg:last-child{border-bottom:0}
.pkg-name{font-family:var(--mono); font-size:13.5px; font-weight:500; word-break:break-all}
.pkg-ver{font-family:var(--mono); font-size:11.5px; color:var(--ink-3)}
.pkg-eco{
  font-family:var(--mono); font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-3); border:1px solid var(--rule); border-radius:2px; padding:1px 6px;
}
.pkg-note{flex:1 1 100%; font-size:14px; color:var(--ink-2); margin:2px 0 0}
.pkg-link{
  font-family:var(--mono); font-size:11.5px; color:var(--ink-2);
  text-decoration:none; border-bottom:1px solid var(--rule); margin-left:auto;
  min-height:var(--tap); display:inline-flex; align-items:center;
}
.pkg-link:hover{color:var(--ink); border-bottom-color:var(--ink)}
@media(max-width:600px){.pkg-link{margin-left:0}}

.lic-text{
  margin-top:14px; background:var(--slab); color:var(--cream-2);
  border-radius:4px; padding:20px 18px; overflow-x:auto;
  font-family:var(--mono); font-size:12px; line-height:1.75; white-space:pre-wrap;
}
details.lic-details{margin-top:16px; border:1px solid var(--rule); border-radius:4px;
  background:var(--raised); padding:0}
details.lic-details > summary{
  font-family:var(--mono); font-size:12px; letter-spacing:.04em; cursor:pointer;
  padding:0 16px; min-height:var(--tap); display:flex; align-items:center; color:var(--ink-2);
}
details.lic-details > summary:hover{color:var(--ink)}
details.lic-details[open] > summary{border-bottom:1px solid var(--rule)}
.lic-details-body{padding:4px 16px 16px}
.lic-details-body .lic-text{margin-top:12px}

/* ============================================================
   CHANGELOG PAGE
   ============================================================ */
.cl-rel{margin-top:clamp(38px,5vw,60px); padding:0}
.cl-rel:first-child{margin-top:0}
.cl-h{
  display:flex; align-items:baseline; gap:14px; flex-wrap:wrap;
  padding-bottom:10px; border-bottom:1px solid var(--rule);
}
.cl-h h2{font-family:var(--mono); font-size:clamp(1.1rem,2.6vw,1.4rem); font-weight:600;
  letter-spacing:-.01em}
.cl-h time{font-family:var(--mono); font-size:12px; color:var(--ink-3)}
.cl-tag{
  font-family:var(--mono); font-size:11.5px; color:var(--ink-2); text-decoration:none;
  border-bottom:1px solid var(--rule); margin-left:auto;
  min-height:var(--tap); display:inline-flex; align-items:center;
}
.cl-tag:hover{color:var(--ink); border-bottom-color:var(--ink)}
@media(max-width:600px){.cl-tag{margin-left:0}}
.cl-intro{margin:16px 0 0; font-size:15.5px; color:var(--ink-2); max-width:64ch}

.cl-sec{margin-top:26px}
.cl-sec h3{
  font-family:var(--mono); font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-3); font-weight:600; margin-bottom:12px;
}
.cl-sec ul{list-style:none; margin:0; padding:0; display:grid; gap:14px}
.cl-sec li{
  padding-left:18px; position:relative; max-width:74ch;
  font-size:15px; color:var(--ink-2); line-height:1.62;
}
.cl-sec li::before{content:"·"; position:absolute; left:5px; color:var(--gold)}
.cl-sec li p{margin:0}
.cl-sec li p + p{margin-top:10px}
.cl-sec strong{color:var(--ink); font-weight:600}
.cl-sec code{font-family:var(--mono); font-size:.88em; background:var(--panel);
  border:1px solid var(--rule-soft); border-radius:2px; padding:1px 4px}

/* A release saying what it cannot do is the reason to publish this page,
   so those sections are set apart rather than buried under "Added". */
.cl-sec.is-caveat{
  margin-top:30px; border-left:3px solid var(--gold);
  background:var(--gold-soft); border-radius:0 4px 4px 0; padding:18px 20px;
}
.cl-sec.is-caveat h3{color:var(--gold-ink)}
.cl-sec.is-caveat li::before{color:var(--gold-ink)}

/* ============================================================
   NO-COOKIE NOTICE

   Deliberately not shaped like a consent banner: no Accept button, no
   overlay, no blocking. It states a fact and offers a link, so there is
   nothing to agree to. A single dismiss control, and it leaves on its own
   after five seconds (DISMISS_AFTER in site.js).

   It cannot remember that you closed it. Remembering would mean writing to
   the device, which is precisely what it says the site does not do, so it
   appears on every page load. That is the honest cost of the notice, not a
   bug to fix with localStorage.
   ============================================================ */
.notice{
  position:fixed; z-index:70;
  right:max(18px, env(safe-area-inset-right));
  bottom:max(18px, env(safe-area-inset-bottom));
  max-width:330px;
  display:flex; align-items:flex-start; gap:10px;
  background:var(--raised); border:1px solid var(--rule);
  border-left:3px solid var(--gold); border-radius:4px;
  padding:12px 12px 12px 14px;
  box-shadow:0 10px 30px -18px rgba(0,0,0,.4);
  animation:notice-in .28s ease both;
}
.notice[hidden]{display:none}
.notice p{
  margin:0; font-family:var(--mono); font-size:11.5px; line-height:1.7; color:var(--ink-2);
}
.notice b{color:var(--ink); font-weight:600}
.notice a{color:var(--gold-ink); text-decoration:none; border-bottom:1px solid var(--rule)}
.notice a:hover{border-bottom-color:var(--gold-ink)}
.notice-x{
  flex:none; margin:-4px -4px 0 0; width:26px; height:26px;
  display:inline-flex; align-items:center; justify-content:center;
  background:none; border:0; border-radius:3px; cursor:pointer;
  font-family:var(--mono); font-size:16px; line-height:1; color:var(--ink-3);
}
.notice-x:hover{color:var(--ink); background:var(--panel)}
@keyframes notice-in{from{opacity:0; transform:translateY(8px)}to{opacity:1; transform:none}}
@media(max-width:520px){
  .notice{left:max(14px, env(safe-area-inset-left)); right:max(14px, env(safe-area-inset-right)); max-width:none}
}
@media(prefers-reduced-motion:reduce){.notice{animation:none}}

/* ============================================================
   LEGAL PAGES (imprint, privacy)
   Prose in the body face rather than the mono chrome voice: these are
   documents to be read, not labels.
   ============================================================ */
.lang-switch{
  max-width:var(--max); margin:0 auto; padding:14px var(--pad) 0;
  font-family:var(--mono); font-size:11.5px;
}
.lang-switch a{color:var(--ink-3); text-decoration:none; border-bottom:1px solid var(--rule)}
.lang-switch a:hover{color:var(--ink); border-bottom-color:var(--ink)}

.legal{margin:16px 0 0; color:var(--ink-2); font-size:15px; max-width:68ch; line-height:1.7}
.legal a{color:var(--ink); border-bottom:1px solid var(--rule)}
.legal a:hover{border-bottom-color:var(--ink)}
.legal-list{margin:16px 0 0; padding-left:20px; max-width:68ch}
.legal-list li{color:var(--ink-2); font-size:15px; line-height:1.7; margin-bottom:8px}
.legal-list li::marker{color:var(--gold)}
.legal-code{margin:12px 0 0; overflow-x:auto}
.legal-code code{
  font-family:var(--mono); font-size:12px; color:var(--ink);
  background:var(--panel); border:1px solid var(--rule-soft);
  border-radius:3px; padding:8px 10px; display:inline-block; white-space:nowrap;
}
/* Guidance for whoever fills the placeholders in. Delete the note, not the fact. */
.legal-note{
  margin:14px 0 0; max-width:68ch;
  font-family:var(--mono); font-size:11.5px; line-height:1.7; color:var(--ink-3);
  border-left:2px solid var(--gold); padding-left:12px;
}
.legal-note a{color:var(--ink-2)}

/* ---------------- footer ---------------- */
footer{border-top:1px solid var(--rule); padding:40px 0 calc(48px + env(safe-area-inset-bottom))}
.foot-in{display:flex; flex-wrap:wrap; gap:22px; justify-content:space-between; align-items:flex-start}
.foot-in p{margin:0; font-family:var(--mono); font-size:12px; color:var(--ink-3); line-height:1.9}
.foot-links{display:flex; gap:20px; flex-wrap:wrap}
.foot-links a{font-family:var(--mono); font-size:12px; color:var(--ink-2);
  text-decoration:none; border-bottom:1px solid var(--rule)}
.foot-links a:hover{color:var(--ink); border-bottom-color:var(--ink)}
@media(max-width:820px){
  .foot-links a{min-height:var(--tap); display:inline-flex; align-items:center}
}
@media(max-width:600px){
  .foot-links{flex-direction:column; gap:0; width:100%}
  .foot-links a{min-height:var(--tap); display:flex; align-items:center;
    border-bottom:1px solid var(--rule-soft)}
}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{animation-duration:.001ms !important; transition-duration:.001ms !important}
}
