/* ==========================================================================
   SYRINX VENTURES — SITE STYLESHEET
   One stylesheet for the whole site. Every page loads exactly this file plus
   assets/fonts.css; there is no per-page <style> block and no second copy of
   any token. (An audit of the previous site found 49% duplicated CSS across
   three files with the tokens already drifting apart. This is that fix — if
   a value is not in this file, it is not in the design.)

   Design frozen from the chosen mockup, b2-type-baskerville.html, archived
   outside this repo at ~/Developer/syrinxventures-brand/mockups/ (it and its
   ~110 comparison fonts have no business on a public CDN). Do not re-derive.

   --------------------------------------------------------------------------
   PAGE SKELETON — the contract every page must follow
   --------------------------------------------------------------------------
   Copy this. Class names and nesting are load-bearing: .sheet carries the
   page measure and gutters, the full-bleed rules and the band deliberately
   sit OUTSIDE it, and every module below is written against this shape.

   <!doctype html>
   <html lang="en">
   <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>PAGE TITLE — Syrinx Ventures</title>
   <meta name="description" content="PAGE DESCRIPTION">
   <link rel="canonical" href="https://syrinxventures.com/PATH/">
   <meta property="og:type" content="website">
   <meta property="og:url" content="https://syrinxventures.com/PATH/">
   <meta property="og:title" content="PAGE TITLE — Syrinx Ventures">
   <meta property="og:description" content="PAGE DESCRIPTION">
   <meta property="og:image" content="https://syrinxventures.com/assets/og.jpg">
   <meta property="og:site_name" content="Syrinx Ventures">
   <meta name="twitter:card" content="summary_large_image">
   <meta name="theme-color" content="#F8F7F5" media="(prefers-color-scheme: light)">
   <meta name="theme-color" content="#12110F" media="(prefers-color-scheme: dark)">
   <link rel="icon" href="/favicon-32x32.png" sizes="32x32">
   <link rel="apple-touch-icon" href="/apple-touch-icon.png">
   <link rel="stylesheet" href="/assets/fonts.css">
   <link rel="stylesheet" href="/assets/site.css">
   </head>
   <body>
   <a class="skip" href="#main">Skip to content</a>

   <header class="masthead">
     <div class="sheet">
       <div class="topbar">
         <span class="stamp apparatus">Syrinx Ventures</span>
         <nav class="topnav" aria-label="Primary">
           <ul role="list">
             <li><a href="/">Home</a></li>
             <li><a href="/picsift/">PicSift</a></li>
             <li><a href="/kindlefill/">KindleFill</a></li>
             <li><a href="/about/">About</a></li>
             <li><a href="/contact/">Contact</a></li>
           </ul>
         </nav>
       </div>

       <div class="nameplate">
         THE NAMEPLATE IS NEVER THE h1. It is masthead furniture that repeats
         on every page; the h1 belongs to what the page is about and lives in
         <main>. One rule, no per-page exception.
         ON THE HOME PAGE (nowhere to link to):
           <p class="nameplate-name"><span class="mark" aria-hidden="true"></span>Syrinx Ventures</p>
         ON EVERY OTHER PAGE, a route back:
           <p class="nameplate-name"><a href="/"><span class="mark" aria-hidden="true"></span>Syrinx Ventures</a></p>
         .nameplate-name is not tied to a tag, so both forms are styled.
       </div>
     </div>

     <div class="masthead-rule"></div>

     <div class="sheet">
       <p class="dateline">
         <span class="apparatus lead-stamp">Washington State · Independent</span>
         <span class="apparatus">syrinxventures.com</span>
       </p>
     </div>
   </header>

   <main id="main">
     ... page sections, each a <section class="sheet ..."> or a
     <section class="..."> whose children are .sheet wrappers when a rule
     needs to run full-bleed ...
   </main>

   <div class="band">
     <div class="sheet">
       <div class="band-top">
         <span class="band-name"><span class="mark" aria-hidden="true"></span>Syrinx Ventures</span>
       </div>
       <p class="reprise">A small company that <span class="soft">publishes software</span>.</p>
       <div class="reprise-rule"></div>
       <footer class="colophon">
         <p>© 2026 Syrinx Ventures LLC · Washington State</p>
         <ul role="list">
           <li><a href="/privacy/">Privacy</a></li>
           <li><a href="/terms/">Terms</a></li>
         </ul>
       </footer>
     </div>
   </div>
   </body>
   </html>

   NAV: mark the current page with aria-current="page" on the <a> and nothing
   else — the visible treatment is driven off the attribute, so there is no
   second class to forget. On the home page that is <a href="/"
   aria-current="page">Home</a>. Never mark two.

   --------------------------------------------------------------------------
   MODULES — the shared components, and the rules that keep pages consistent.
   Use these; do not write a variant. If a page needs something not listed
   here, add it to THIS file and to THIS list.
   --------------------------------------------------------------------------
   HEADING LADDER — fixed, and it does not skip.
     h1  the page subject, exactly one, inside <main>. On home it is the
         .lede headline; on /picsift/ it is the product name.
     h2  a section: a .dispatch-head product name, or an .about / .contact
         head where that section is a peer of the dispatches.
     h3  a .cols.dense .col head, and any sub-head inside a section.
     The nameplate is never a heading. See above.

   <section class="sheet lede">      thesis: h1 + .lede-rule + .standfirst
                                     (the drop cap is automatic on
                                     .standfirst p — do not add a class)
   <section class="dispatch">        a numbered section. Its .dispatch-rule
                                     and .dispatch-head must each sit in
                                     their own .sheet so the 4px rule runs
                                     the full page width.
   .kicker / .apparatus              the two small-caps textures. .kicker is
                                     the display face (section labels),
                                     .apparatus the reading face (stamps,
                                     dateline, colophon).
   .cols.dense                       1 -> 2 -> 3 columns by width. Col heads
                                     are h3.
   .measure / .fineprint             single wide measure / legal small print.
   figure.plate + .shot > .clip      ONLY for 1600x1000 PicSift window
                                     captures. See the PLATES note below.
   figure.plate + .frame             every other screenshot; keeps the mat.
   .action                           the product's own actions, closed by the
                                     amber --r-lede rule. Exactly ONE .chip
                                     per action row — the place you get the
                                     thing (App Store, source repo). Every
                                     other link in the row is .alt-link:
                                     "two chips side by side read as two
                                     products". .chip-ghost is the chip for a
                                     free/open-source product.
   .onward                           the route out of a section to its own
                                     page ("More on PicSift", "Read about the
                                     company"). Hair rule, one .alt-link.
                                     NOT an .action — the amber rule is
                                     reserved. Use this for every internal
                                     route, on every page.
   .contact                          the address list. Rows are <li> bound by
                                     hair rules; each has one mailto <a> and
                                     one .note.

   --------------------------------------------------------------------------
   TYPE
     Display — "Libre Baskerville" 400 / 700 / 400i. Nameplate, headlines,
       product names, decks, kickers, chips, reprise.
     Reading — "Alegreya Sans" 400 / 500 / 700 / 400i. Body, standfirst,
       captions, apparatus, nav, contact, colophon.
   font-synthesis-weight is OFF site-wide. Libre Baskerville ships 400 and 700
   only, so any 500/600 set in the display face would silently snap to 700.
   700 in the display face is spent on exactly three things per page: the
   masthead nameplate, the product name(s), and the name again on black.

   NO SMALL CAPS, NO OLDSTYLE FIGURES — neither face ships them in this subset
   and none are synthesised. Small-caps texture is tracked FULL caps, always.

   PALETTE — a neutral warm grey. Putty, not paper: NOT tan, sand, cream or
   beige. The guard is numeric — the stock's R-B spread is 3 steps out of 255
   and the mat's is 6. Explicitly not the Tailwind stone ramp.
   Brand amber #DC7607 measures 2.96:1 on the light stock, so it NEVER sets
   text on a light ground; the light-scheme text accent is #9A4D00 and
   full-strength amber is reserved for the black band and for dark mode.
   Accent is never the sole carrier of link-ness: every link also has an
   underline, a border, or a weight step.

   CONTRAST, measured (WCAG 2.1, sRGB) — all text pairs >= 4.5:1:
     LIGHT   ink   #0F0E0C on paper #F8F7F5 = 18.02:1
             ink-2 #4A4741 on paper #F8F7F5 =  8.65:1
             accnt #9A4D00 on paper #F8F7F5 =  5.71:1
             ink   #0F0E0C on mat   #E3E1DD = 14.77:1
             ink-2 #4A4741 on mat   #E3E1DD =  7.09:1
             accnt #9A4D00 on mat   #E3E1DD =  4.68:1
             paper #F8F7F5 vs mat   #E3E1DD =  1.22:1  (stock step)
             rule  #CBC7BF on paper #F8F7F5 =  1.57:1  (non-text)
             brand #DC7607 on paper #F8F7F5 =  2.96:1  (never sets text)
     DARK    ink   #F2F0EB on paper #12110F = 16.57:1
             ink-2 #A8A49B on paper #12110F =  7.59:1
             accnt #DC7607 on paper #12110F =  5.96:1
             ink   #F2F0EB on mat   #23211E = 14.10:1
             ink-2 #A8A49B on mat   #23211E =  6.46:1
             accnt #DC7607 on mat   #23211E =  5.08:1
             paper #12110F vs mat   #23211E =  1.18:1  (stock step)
             rule  #37342E on paper #12110F =  1.52:1  (non-text)
     BAND (committed to black in BOTH schemes — it does not invert)
             #F8F7F5 on #0F0E0C = 18.02:1
             #C8C4BB on #0F0E0C = 11.09:1
             #DC7607 on #0F0E0C =  6.10:1
             #37342E on #0F0E0C =  1.56:1  (non-text rule)

   RULE WEIGHTS — rule weight is meaning, and these four values are the whole
   vocabulary. Do not introduce a fifth. Rules are page structure, not type:
   they do not scale with the display ladder.
     --r-heavy  4px  solid ink    — a top-level break: masthead, new section.
     --r-mid    2px  solid ink    — peers inside a section: item from item.
                                    Also the nav's current-page mark, which is
                                    exactly "one of a peer set".
     --r-hair   1px  solid rule   — binding: caption to plate, column to
                                    column, row to row.
     --r-lede   2px  solid accent — mid weight, accent hue. The only coloured
                                    rule on the page, so it needs no unique
                                    thickness to be recognised. Reserved for
                                    the lede and for product actions.

   PLATE MAT is a real change of stock: paper -> mat is a 1.22:1 luminance
   step in light and 1.18:1 in dark, painted on the frame with padding so it
   surrounds every screenshot on all four sides.

   DARK MODE: handled by redefining :root tokens, nothing else. Screenshots
   are light-UI product shots and are NEVER filtered or dimmed. Their mats
   change stock.

   URLs: root-relative everywhere (/assets/..., /picsift/). This site deploys
   to a domain root. Note that url() inside THIS file resolves against
   /assets/, which is why the mark's mask is written /assets/sv-mark.png and
   not assets/sv-mark.png.
   ========================================================================== */

:root{
  color-scheme: light;
  --paper:#F8F7F5;
  --plate:#E3E1DD;
  --ink:#0F0E0C;
  --ink-2:#4A4741;
  --rule:#CBC7BF;
  --accent:#9A4D00;
  --ring:#0F0E0C;

  --band:#0F0E0C;
  --band-ink:#F8F7F5;
  --band-ink-2:#C8C4BB;
  --band-accent:#DC7607;
  --band-rule:#37342E;

  --r-heavy:4px;
  --r-mid:2px;
  --r-hair:1px;
  --r-lede:2px;

  /* Deliberately uneven. No single value is allowed to become "the gap". */
  --a:.3rem; --b:.7rem; --c:1.15rem; --d:2rem;
  --e:3.25rem; --f:5.5rem; --g:9rem; --h:13.5rem;

  --gut:clamp(1.15rem, 4vw, 3.25rem);
  --page:1440px;

  --display:"Libre Baskerville",Georgia,"Times New Roman",serif;
  --text:"Alegreya Sans","Helvetica Neue",Arial,sans-serif;
}

@media (prefers-color-scheme: dark){
  :root{
    color-scheme: dark;
    --paper:#12110F;
    --plate:#23211E;
    --ink:#F2F0EB;
    --ink-2:#A8A49B;
    --rule:#37342E;
    --accent:#DC7607;
    --ring:#DC7607;
  }
}

*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  /* Alegreya Sans sets narrow and optically small: up ~7% on a neutral sans,
     leading down to 1.52, so absolute line spacing and page length hold. */
  font-family:var(--text);
  font-weight:400;
  font-size:clamp(1.07rem,1.01rem + .3vw,1.2rem);
  line-height:1.52;
  font-synthesis-weight:none;
  overflow-x:hidden;
}
img{max-width:100%;height:auto;display:block;}

/* --- shared shell ------------------------------------------------------ */
.sheet{max-width:var(--page);margin-inline:auto;padding-inline:var(--gut);}

/* --- focus: two rings, because the black band eats a black one ---------- */
a:focus-visible,
:focus-visible{
  outline:3px solid var(--ring);
  outline-offset:3px;
  border-radius:2px;
}
.band a:focus-visible{outline-color:var(--band-accent);}

.skip{
  position:absolute;left:-9999px;top:0;z-index:50;
  background:var(--ink);color:var(--paper);
  font-family:var(--text);
  font-weight:700;font-size:1.02rem;letter-spacing:.09em;
  text-transform:uppercase;text-decoration:none;
  padding:.9rem 1.4rem;
}
.skip:focus{left:var(--gut);top:.5rem;}

/* --- display type ------------------------------------------------------ */
/* Kickers are the display face at its designed size. Full caps, tracked
   OPEN — no small-cap synthesis; the face ships none. Caps Baskerville is
   wide, so apparatus tracking comes back to .14em here. */
.kicker{
  font-family:var(--display);
  font-weight:400;
  font-size:clamp(.8rem,.76rem + .2vw,.92rem);
  letter-spacing:.14em;
  text-transform:uppercase;
  line-height:1.35;
  margin:0;
}

/* Apparatus: the reading face, small, tracked. Narrower than the display
   face, so it keeps a wider .17em without smearing. */
.apparatus{
  font-family:var(--text);
  font-weight:500;
  letter-spacing:.17em;
  text-transform:uppercase;
  font-size:.86rem;
}

/* ======================================================================
   MASTHEAD
   ====================================================================== */
.masthead{padding-top:var(--c);}
.topbar{
  display:flex;flex-wrap:wrap;align-items:baseline;
  justify-content:space-between;gap:var(--a) var(--d);
  border-bottom:var(--r-hair) solid var(--rule);
}
.topbar .stamp{
  color:var(--ink-2);
  padding-block:.9rem;
}

/* ----------------------------------------------------------------------
   PRIMARY NAV
   Five items in the topbar's own vocabulary: the reading face, tracked
   caps, sitting on the hair rule that already closes the topbar. No
   hamburger — five short words wrap to two rows inside 375px and stay
   legible, and a disclosure button would be the only piece of interface
   chrome on an otherwise printed page.

   At 375px the topbar's `space-between` would strand the "Syrinx Ventures"
   stamp on a line of its own with the nav pushed hard right. Below 600px
   the stamp is therefore given the full row and the nav starts a new one,
   left-aligned — which is what a broadsheet does anyway.

   Each item reserves a 2px transparent bottom border, so the current-page
   and hover marks cost no layout shift.

   CURRENT PAGE — 2px INK, the peer-separator weight from the rule system:
   marking one of a peer set is precisely what --r-mid means. Hover is 2px
   ACCENT plus accent ink, so the two states are never confusable, and the
   current item is legible with colour removed because it also steps to 700.
   Driven off [aria-current="page"] so there is no second class to forget.
   ---------------------------------------------------------------------- */
.topnav ul{
  display:flex;flex-wrap:wrap;gap:0 var(--d);
  list-style:none;margin:0;padding:0;
}
.topnav a{
  display:flex;align-items:center;min-height:44px;
  padding-block:.55rem;
  color:var(--ink);
  font-family:var(--text);
  font-weight:500;font-size:1rem;
  letter-spacing:.15em;text-transform:uppercase;
  text-decoration:none;
  border-bottom:var(--r-mid) solid transparent;
}
.topnav a:hover{border-bottom-color:var(--accent);color:var(--accent);}
.topnav a[aria-current="page"]{
  border-bottom-color:var(--ink);
  font-weight:700;
}
.topnav a[aria-current="page"]:hover{
  border-bottom-color:var(--accent);
}
@media (max-width:599px){
  .topbar{gap:0;}
  .topbar .stamp{flex:1 0 100%;padding-block:.9rem .5rem;}
  .topnav{flex:1 0 100%;}
  /* Tighter tracking and a smaller gap only where the row count matters. */
  .topnav ul{gap:0 var(--c);}
  .topnav a{letter-spacing:.1em;font-size:.94rem;}
}

/* MARK / NAMEPLATE LOCKUP — cap-height match, not a nudge.
   The mark lives INSIDE the nameplate as an inline-block on the text
   baseline: vertical-align:baseline puts its bottom edge ON the baseline,
   height:0.77em puts its top edge exactly on the cap line. Libre Baskerville
   measures 0.77 cap height, so those are the same two edges as a capital S.
   No transform, nothing to re-tune when the type changes size — the em does
   it. The font-size lives on the lockup and the name inherits it, so one
   clamp drives both. */
.nameplate{
  display:flex;align-items:center;gap:clamp(.55rem,1.5vw,1rem);
  padding-block:clamp(var(--c),3vw,var(--e)) var(--c);
  font-size:clamp(1.6rem,4.6vw,3.4rem);
}
.mark{
  display:inline-block;
  vertical-align:baseline;
  height:0.77em;
  width:auto;
  aspect-ratio:1024/766;
  margin-inline-end:.28em;
  background-color:var(--ink);
  /* Root-relative: url() here resolves against /assets/, and a bare
     "assets/sv-mark.png" would become /assets/assets/sv-mark.png — a mask
     that fails silently rather than erroring. */
  -webkit-mask:url(/assets/sv-mark.png) center/contain no-repeat;
  mask:url(/assets/sv-mark.png) center/contain no-repeat;
}
/* One of the page's THREE display-face 700s. Deliberately NOT tied to a tag:
   it is the <h1> on the home page and a linked <p> everywhere else. */
.nameplate-name{
  font-family:var(--display);
  font-weight:700;
  font-size:1em;
  line-height:.9;
  letter-spacing:-.03em;
  text-transform:uppercase;
  margin:0;
}
/* When the nameplate is a link back home it must not read as body link
   chrome — it inherits the ink and loses the underline, and the whole
   lockup is the target. */
.nameplate-name a{
  color:inherit;
  text-decoration:none;
  display:inline-block;
  /* TARGET SIZE. inline-block makes the hit area exactly the cap-height
     lockup — 24.8px tall at 375px, under the 44px minimum. Grow it with
     padding and take the space straight back with an equal negative margin,
     so the masthead's height and the lockup's position stay identical to the
     home page, where the nameplate is a plain <p> and this rule never
     applies. Deliberately NOT display:flex with min-height — flex items
     ignore vertical-align, which is the mechanism anchoring .mark to the
     text baseline at cap height. */
  /* 12px, not 10: the lockup is 23px tall at 375px, so 10px each side
     lands at 43 — one pixel short of the 44 minimum. Measured, not
     assumed. 12 gives 47 and keeps a little slack as type scales. */
  padding-block:12px;
  margin-block:-12px;
}
.nameplate-name a:hover{color:var(--accent);}
.nameplate-name a:hover .mark{background-color:var(--accent);}

.masthead-rule{border-top:var(--r-heavy) solid var(--ink);}
.dateline{
  display:flex;flex-wrap:wrap;justify-content:space-between;
  gap:var(--a) var(--d);
  padding-block:.75rem;
  border-bottom:var(--r-hair) solid var(--rule);
  color:var(--ink-2);
}
.dateline .lead-stamp{color:var(--accent);}

/* ======================================================================
   LEDE — the thesis. The largest thing on the page, not the loudest: 400
   weight in a face whose 400 already carries weight, and the step down to
   the standfirst stays close enough that the two read as one utterance.
   ====================================================================== */
.lede{padding-block:clamp(var(--d),4vw,var(--f)) 0;}
.lede h1,
.lede h2{
  font-family:var(--display);
  font-weight:400;
  font-size:clamp(1.65rem,5.1vw,3.8rem);
  /* Caps only, so leading can close; .96 leaves a 0.19em band between cap
     bottoms and the next cap top, which is where Baskerville stops feeling
     cramped. */
  line-height:.96;
  letter-spacing:-.028em;
  text-transform:uppercase;
  margin:0;
  text-wrap:balance;
}
.lede .soft{color:var(--accent);}
.lede-rule{
  border-top:var(--r-lede) solid var(--accent);
  margin-top:clamp(var(--c),2.2vw,var(--d));
}
.standfirst{
  padding-block:var(--c) clamp(var(--d),3.6vw,var(--e));
  border-bottom:var(--r-mid) solid var(--ink);
}
.standfirst p{
  margin:0;
  font-size:clamp(1.2rem,1.06rem + .58vw,1.62rem);
  line-height:1.38;
}
/* Drop cap, solved by measurement; every value in em so it holds at every
   clamp step. cap height = .77 x 2.63em = 2.02em, exactly the distance from
   line 1's cap top to line 2's baseline at the standfirst's 1.38 leading.
   line-height .78 sets the float's box, whose negative half-leading lifts the
   glyph; margin-top .16em lands the cap top on line 1's cap top and the cap
   foot on line 2's baseline, both inside a pixel.
   NOTE the unit trap: margin-top on ::first-letter is em of the FIRST LETTER,
   i.e. 2.63x the body em. Measured, not assumed. */
.standfirst p::first-letter{
  font-family:var(--display);
  font-weight:400;
  font-size:2.63em;
  line-height:.78;
  float:left;
  padding-right:.07em;
  margin-top:.16em;
  color:var(--accent);
}

/* ======================================================================
   PLATES — screenshots as printed plates: rule above, caption below.

   TREATMENT B. The PicSift captures arrive with two frames already painted
   into the JPEG — a white page margin with the window's drop shadow on it,
   and the macOS window itself. The cropper below deletes the first and clips
   exactly to the second, INCLUDING the window's own 25.5px corner radius, so
   the visible edge follows the curve instead of cutting a grey arc across it.

   Geometry (verified identical across picsift-01/02/04/05, all 1600x1000):
     window rect 58-1542 x 18-945; corner radius 25.5px, circle-fitted,
     RMS <= 0.28px. Crop box (60,20)-(1540,943) sits 2px inside the window on
     every side; the 23px clip radius sits >= 1.8px inside the true arc. Max
     overshoot beyond the real window boundary, over all 1,365,040 cropped
     pixels: 0.000px.

   The radius lives on the CLIPPING WRAPPER, never on the <img>: the image is
   over-scaled to 108% and pulled by negative percentages, so a radius on it
   would be drawn on the pre-crop rectangle. It is a percentage PAIR because a
   px radius cannot scale with a fluid wrapper; the two values resolve to the
   same absolute length, so the arc stays circular.

   USE .shot ONLY on 1600x1000 PicSift window captures with this exact
   geometry. Anything else — KindleFill, any future full-bleed capture —
   uses .frame and keeps the mat. One rule, two resolutions: exactly one edge
   between app pixels and paper.
   ====================================================================== */
figure.plate{margin:0;}
figure.plate .frame{
  border-top:var(--r-mid) solid var(--ink);
  padding:var(--b) clamp(.7rem,1.5vw,1.3rem) clamp(.7rem,1.5vw,1.3rem);
  background:var(--plate);
}
figure.plate .frame img{
  width:100%;height:auto;
  border:var(--r-hair) solid var(--rule);
}
/* the cropper: used on PicSift plates in place of .frame */
figure.plate .shot{
  position:relative;
  overflow:hidden;
  border-top:var(--r-mid) solid var(--ink);
  margin-top:0;
}
figure.plate .shot .clip{
  position:relative;
  overflow:hidden;
  aspect-ratio:1480/923;
  border-radius:1.5541% / 2.4919%;   /* 23/1480 across, 23/923 down */
  margin-top:var(--b);
}
figure.plate .shot .clip img{
  position:absolute;
  max-width:none;
  width:108.1081%;
  height:auto;
  left:-4.0541%;
  top:-2.1668%;
  border:0;
}
/* one honest edge, as an inset ring so it follows the clip's own curve */
figure.plate .shot .clip::after{
  content:"";
  position:absolute;
  inset:0;
  border:var(--r-hair) solid var(--rule);
  border-radius:inherit;
  pointer-events:none;
}
figure.plate figcaption{
  margin-top:.55rem;
  padding-top:.5rem;
  border-top:var(--r-hair) solid var(--rule);
  color:var(--ink-2);
  font-size:.95rem;
  line-height:1.38;
}
/* Plate number: reading face at 700. It has to out-rank the caption it sits
   inside at 0.95rem, and the display face at that size would only add width. */
figure.plate figcaption b{
  font-family:var(--text);
  font-weight:700;font-size:.94rem;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink);
  margin-right:.55em;
}
figure.plate figcaption i{font-style:italic;}

.plate-lead{padding-top:clamp(var(--d),3.4vw,var(--e));}

/* ======================================================================
   DISPATCHES — a numbered section: heavy rule, head, body, action.
   ====================================================================== */
.dispatch{padding-top:clamp(var(--f),8vw,var(--h));}
.dispatch-rule{border-top:var(--r-heavy) solid var(--ink);}
.dispatch-head{
  display:grid;
  grid-template-columns:1fr;
  gap:var(--b);
  padding-block:var(--c) var(--d);
  border-bottom:var(--r-hair) solid var(--rule);
}
.dispatch-head .num{color:var(--accent);}
/* Two of the page's THREE display-face 700s: the product names. */
.dispatch-head h2,
.dispatch-head h3{
  font-family:var(--display);
  font-weight:700;
  font-size:clamp(1.5rem,3.5vw,2.4rem);
  line-height:1;
  letter-spacing:-.022em;
  text-transform:uppercase;
  margin:0;
}
/* The deck is the display face in ITALIC — Baskerville's italic is a real
   cut, not a slant, and it is the one place where the display face speaks in
   a second voice. 400 only; there is no bold italic and none is synthesised. */
.deck{
  margin:0;
  font-family:var(--display);
  font-weight:400;
  font-size:clamp(1rem,.9rem + .42vw,1.26rem);
  font-style:italic;
  line-height:1.3;
  letter-spacing:-.008em;
  color:var(--ink-2);
}

/* body of a dispatch — column counts step up with width */
.cols{margin:0;padding-block:var(--d) 0;}
.cols p{margin:0 0 var(--c);}
.cols p:last-child{margin-bottom:0;}
/* THREE COLUMNS, THREE THOUGHTS
   Grid, not CSS multi-column: three separate short items, each with its own
   kicker, so a column can be read on its own and in any order.
   49rem is a MEASURED cap, not a converted one — it is in rem, so it does not
   adapt to the face at all, and it puts a column on 33 characters of Alegreya
   Sans. Do not raise it. */
.cols.dense{
  max-width:49rem;
  display:grid;
  grid-template-columns:1fr;
  gap:var(--c) var(--d);
}
.cols.dense .col{ margin:0; }
.cols.dense .col h3,
.cols.dense .col h4{
  font-family:var(--display);
  font-weight:400;
  font-size:.85rem;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--ink-2);
  margin:0 0 .4rem;
  padding-bottom:.32rem;
  border-bottom:var(--r-hair) solid var(--rule);
}
.cols.dense .col p{ margin:0; }

/* a wide, single-measure passage — deliberately the opposite density.
   `ch` is the "0" advance and does not track average character width across
   a face change: 55ch of Alegreya Sans runs 77 characters. Measured. */
.measure{max-width:55ch;}

/* action row: link as a padded chip, never inline in prose */
.action{
  display:flex;flex-wrap:wrap;align-items:center;
  gap:var(--b) var(--d);
  margin-top:clamp(var(--c),2.4vw,var(--d));
  padding-top:var(--c);
  border-top:var(--r-lede) solid var(--accent);
}
.action .meta{
  color:var(--ink-2);
  font-family:var(--text);
  font-weight:500;letter-spacing:.13em;text-transform:uppercase;
  font-size:.92rem;
  line-height:1.4;
  flex:1 1 15rem;
}
/* Secondary route to the same product: the store is where you get the app,
   the site is where you read about it. Text link, NEVER a second chip — two
   chips side by side would read as two products. This is why "Read more
   about PicSift" and "picsift.com" are both .alt-link and only the store /
   the source repo gets a chip. Set in the display face because it belongs to
   the action, not to the apparatus. */
a.alt-link{
  display:inline-flex;align-items:center;min-height:48px;
  color:var(--accent);
  font-family:var(--display);
  font-weight:400;letter-spacing:.06em;text-transform:uppercase;
  font-size:.86rem;
  text-decoration:underline;
  text-decoration-thickness:2px;
  text-underline-offset:.24em;
}
a.alt-link:hover{color:var(--ink);}

a.chip{
  display:inline-flex;align-items:center;min-height:48px;
  padding:.65rem 1.25rem;
  background:var(--ink);
  color:var(--paper);
  border:var(--r-mid) solid var(--ink);
  text-decoration:none;
  font-family:var(--display);
  font-weight:400;
  /* Caps Baskerville is wide. Measured, the 44-character GitHub URL sets on
     ONE line at 1440px and wraps to three inside the 375px gutter without
     pushing the document past its client width. */
  font-size:clamp(.82rem,.77rem + .2vw,.95rem);
  letter-spacing:.03em;text-transform:uppercase;
  line-height:1.25;
  /* Same decision as .contact a: long URL tokens must be allowed to break,
     or a 36-char github path overflows the 375px viewport. */
  min-width:0;
  overflow-wrap:anywhere;
}
a.chip:hover{background:var(--accent);border-color:var(--accent);color:var(--paper);}
a.chip-ghost{
  background:transparent;color:var(--ink);
  border:var(--r-mid) solid var(--ink);
  text-decoration:underline;text-underline-offset:.24em;
  text-decoration-thickness:2px;
}
a.chip-ghost:hover{background:var(--ink);color:var(--paper);}

/* 50ch = 70 characters, measured. Same correction as .measure. */
.fineprint{
  margin:var(--c) 0 0;
  padding-top:.6rem;
  border-top:var(--r-hair) solid var(--rule);
  color:var(--ink-2);
  font-size:.92rem;
  line-height:1.46;
  max-width:50ch;
}

/* ======================================================================
   ABOUT — given the whole width. A full stop.
   Stays in the READING face: it is the page speaking plainly, not a headline.
   ====================================================================== */
.about{padding-top:clamp(var(--f),8vw,var(--h));}
.about-rule{border-top:var(--r-heavy) solid var(--ink);}
.about .kicker{padding-block:var(--c);color:var(--ink-2);}
/* Specificity guard, not decoration. `.about p` below sets font-size,
   line-height and letter-spacing at (0,0,2) and is declared after `.kicker`
   at (0,0,1), so without this the About kicker inherits the big sentence's
   2.7rem and its negative tracking — putting "ABOUT" in Libre Baskerville at
   43px, two pixels off the product names, reading as a competing section
   head. The kicker-below-product-name-below-headline ramp is the composition
   this design is required to hold, so it is restored at (0,0,3). */
.about p.kicker{
  font-size:clamp(.8rem,.76rem + .2vw,.92rem);
  line-height:1.35;
  letter-spacing:.14em;
}
.about p{
  margin:0;
  padding-bottom:clamp(var(--d),3.6vw,var(--f));
  font-size:clamp(1.45rem,1rem + 2.05vw,2.7rem);
  line-height:1.2;
  letter-spacing:-.012em;
  text-wrap:balance;
}
.about p em{font-style:italic;color:var(--accent);}
/* When the About block carries a route onward, the sentence gives up its
   bottom padding and .onward closes the section instead. */
.about p.has-onward{padding-bottom:var(--c);}
.about .onward{margin-bottom:clamp(var(--d),3.6vw,var(--f));}

/* ======================================================================
   ONWARD — the route out of a section to its own page. NOT an .action:
   .action's amber rule is --r-lede, which the rule system reserves for the
   lede and for product actions. A navigational route is a binding, so it
   takes --r-hair. One pattern for every "read more on its own page" link,
   anywhere on the site.
   ====================================================================== */
.onward{
  margin:var(--c) 0 0;
  padding-top:var(--c);
  border-top:var(--r-hair) solid var(--rule);
}

/* ======================================================================
   CONTACT
   ====================================================================== */
.contact{border-top:var(--r-mid) solid var(--ink);padding-top:var(--c);}
.contact .kicker{color:var(--ink-2);}
.contact ul{
  list-style:none;margin:var(--c) 0 0;padding:0;
  display:grid;grid-template-columns:1fr;
  gap:0;
}
.contact li{border-top:var(--r-hair) solid var(--rule);}
.contact li:first-child{border-top:0;}
/* Addresses set in the READING face. They are lowercase strings with an @
   and two dots — the display face would add ~40% width for no gain and put
   support@syrinxventures.com over the edge of a 375px viewport. */
.contact a{
  display:flex;align-items:center;min-height:52px;
  padding-block:.85rem;
  color:var(--ink);
  font-family:var(--text);
  font-weight:500;
  font-size:clamp(1.1rem,1rem + .62vw,1.5rem);
  letter-spacing:0;
  text-decoration:underline;
  text-decoration-thickness:2px;
  text-underline-offset:.18em;
  text-decoration-color:var(--accent);
  word-break:break-word;
}
.contact a:hover{color:var(--accent);}
.contact .note{
  display:block;
  color:var(--ink-2);
  font-family:var(--text);
  font-size:.94rem;
  line-height:1.45;
  padding-bottom:.85rem;
}

/* ======================================================================
   DOC — interior document pages: About, Contact, Privacy, Terms.

   These four pages needed three things the front page never asks for, and
   each is built from the existing vocabulary rather than inventing a new
   one. Promoted here from four identical page-level <style> blocks: one
   decision, one owner.

   1. A SUB-PAGE SECTION HEAD. On the home page every section head is either
      a product name (.dispatch-head, display 700) or the single .about
      kicker. A document's sections are peers of one another, and --r-mid is
      precisely "peers inside a section: item from item", so the head is that
      rule plus spacing, with .kicker supplying the type. No new size, and no
      fourth place spending the display face's 700.
   2. AN INLINE PROSE LINK. Every link on the front page is a .chip or an
      .alt-link — block-ish, set in caps. Prose needs one that sits inside a
      sentence: accent ink plus a 2px underline, so colour is never the sole
      carrier of link-ness. Measured 5.71:1 light, 5.96:1 dark.
   3. THE PER-APP LIST. Rows bound by hair rules — the same binding idiom
      .contact uses — carrying prose rather than an address.
   ====================================================================== */
.doc-sec{
  margin-top:clamp(var(--d),4vw,var(--f));
  border-top:var(--r-mid) solid var(--ink);
}
.doc-sec > h2{
  padding-block:var(--c) var(--b);
  color:var(--ink);
}
/* .standfirst closes with a 2px ink rule of its own, so the first section on
   the page must not draw a second one directly beneath it. Same reason the
   .contact module suppresses its own rule when it opens a .doc-sec. */
.doc-sec-lead{border-top:0;margin-top:0;}
.doc-sec > .contact{border-top:0;padding-top:0;}

/* An over-line label above the page's h1. .kicker sets margin:0, which is
   right inside a padded block and wrong when it leads a lede. */
.lede > .kicker{color:var(--ink-2);padding-bottom:var(--b);}
.lede > .updated{margin:var(--c) 0 0;color:var(--ink-2);}

.prose a{
  color:var(--accent);
  text-decoration:underline;
  text-decoration-thickness:2px;
  text-underline-offset:.18em;
  /* Long addresses must be allowed to break or they overflow at 375px. */
  overflow-wrap:anywhere;
}
.prose a:hover{color:var(--ink);}

.doc-apps{list-style:none;margin:0;padding:0;max-width:55ch;}
.doc-apps li{
  border-top:var(--r-hair) solid var(--rule);
  padding-block:var(--c);
  margin:0;
}
.doc-apps li:first-child{border-top:0;padding-top:0;}
/* The reading face at 700 — the weight step figcaption b uses to outrank the
   text it sits in. NOT tracked caps: Terms sets the product names as
   trademarks, and a text-transform would misrepresent them. */
.doc-apps strong{font-weight:700;color:var(--ink);}

/* The signature block closing a document. */
.doc-sign{
  margin-top:clamp(var(--d),4vw,var(--f));
  padding-top:var(--c);
  border-top:var(--r-hair) solid var(--rule);
  max-width:55ch;
}
.doc-sign p{margin:0;}

/* ======================================================================
   CLOSE — the black band. Committed to one look in both schemes.
   ====================================================================== */
.band{
  background:var(--band);
  color:var(--band-ink);
  margin-top:clamp(var(--f),8vw,var(--h));
  padding-block:clamp(var(--e),6vw,var(--g)) var(--e);
}
.band .band-top{
  display:flex;align-items:center;gap:clamp(.7rem,2vw,1.2rem);
  padding-bottom:var(--c);
  border-bottom:var(--r-hair) solid var(--band-rule);
}
/* The closing mark inherits the whole cap-height lockup from .mark — it sits
   inside .band-name, so its em resolves against that font-size and it scales
   with the words beside it automatically. Only the ink changes. */
.band .mark{background-color:var(--band-accent);}
/* The third and last display-face 700: the company's name again, on black. */
.band .band-name{
  font-family:var(--display);
  font-weight:700;font-size:clamp(1rem,.82rem + .7vw,1.4rem);
  letter-spacing:-.016em;text-transform:uppercase;line-height:1;
}
.reprise{
  margin:clamp(var(--c),2.6vw,var(--d)) 0 0;
  font-family:var(--display);
  font-weight:400;
  /* Held to ONE line at 1440px: the 40 caps of "A SMALL COMPANY THAT
     PUBLISHES SOFTWARE." have to fit the sheet's 1321px, and -.028em is what
     buys the last few pixels. 3.1rem broke it to two. Tuned to THIS string. */
  font-size:clamp(1.5rem,4.2vw,2.8rem);
  line-height:1.02;
  letter-spacing:-.028em;
  text-transform:uppercase;
  text-wrap:balance;
}
.reprise .soft{color:var(--band-accent);}
.reprise-rule{
  border-top:var(--r-lede) solid var(--band-accent);
  margin-top:clamp(var(--c),2.4vw,var(--d));
}

footer.colophon{
  display:flex;flex-wrap:wrap;align-items:center;
  justify-content:space-between;gap:var(--a) var(--d);
  padding-top:.5rem;
  color:var(--band-ink-2);
}
footer.colophon p{
  margin:0;
  font-family:var(--text);
  font-weight:500;letter-spacing:.15em;text-transform:uppercase;
  font-size:.86rem;
}
footer.colophon ul{
  display:flex;flex-wrap:wrap;gap:var(--d);list-style:none;margin:0;padding:0;
}
footer.colophon a{
  display:flex;align-items:center;min-height:44px;
  padding-block:.55rem;
  color:var(--band-ink);
  font-family:var(--text);
  font-weight:700;letter-spacing:.15em;text-transform:uppercase;
  font-size:.86rem;
  text-decoration:underline;
  text-decoration-thickness:2px;
  text-underline-offset:.2em;
  text-decoration-color:var(--band-accent);
}
footer.colophon a:hover{color:var(--band-accent);}

/* ======================================================================
   RESPONSIVE — column counts step 1 -> 2 -> 3.
   A three-column passage at 768px would give ~14ch and read as broken, so
   three columns only appear above 1100px.
   ====================================================================== */
@media (min-width:768px){
  .topbar .stamp{padding-block:1.1rem;}
  .dispatch-head{
    grid-template-columns:minmax(0,1.45fr) minmax(0,1fr);
    align-items:end;
    column-gap:var(--e);
  }
  .dispatch-head .headgroup{grid-column:1;}
  .dispatch-head .deck{grid-column:2;padding-bottom:.3em;}
  .cols.dense{grid-template-columns:1fr 1fr;}
  .plate-row{
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:var(--d);
  }
  .kf-layout{
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,1.35fr);
    gap:var(--e);
    align-items:start;
  }
  .contact ul{grid-template-columns:1fr 1fr;column-gap:var(--e);}
  .contact li:nth-child(2){border-top:0;}
}
@media (min-width:1100px){
  .cols.dense{grid-template-columns:repeat(3,1fr);}
  /* The standfirst deliberately stays a single wide measure: it is only ~172
     characters, so splitting it would give two stub lines per column and
     strand the drop cap. 42ch of Alegreya Sans runs 59 characters. */
  .standfirst p{font-size:1.62rem;max-width:42ch;}
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
}
