/* filmfont article components, promoted from 7 duplicated inline <style> blocks, 2026-08-27.
 *
 * ⛔ THIS IS THE INTERSECTION ONLY. The blocks were NOT identical: all 7 differed, each carrying
 *    article-specific components (.tier-ladder, .vendor-card, .methodology-card and others) on top
 *    of a shared core. Promoting a whole block would have applied one article's components to six
 *    pages that were never designed with them, and dropped rules from the others.
 *    ⭐ Only what EVERY page already has can be hoisted. Differences stay inline, on purpose.
 *
 * Load this BEFORE any remaining inline <style>, so an article can still override a shared rule.
 */
:root{--accent:#c9a96e;--accent-hover:#a88947;--dark:#0e0c0a;--text:#1a1713;--text-light:#6b6256;--border:#e5dcc7;--cream:#f5efe2;--radius:8px;--display:'Bodoni Moda',serif;--body:'Inter',sans-serif;--mono:'JetBrains Mono',monospace;}
.skip-link{position:absolute;left:-9999px;top:0;background:var(--accent-fill,var(--accent));color:#fff;padding:.6rem 1rem;z-index:200;border-radius:0 0 var(--radius) 0;}
.skip-link:focus{left:0;}
.reading-progress{position:fixed;top:0;left:0;right:0;height:3px;background:transparent;z-index:100;pointer-events:none;}
.reading-progress span{display:block;height:100%;width:0;background:var(--accent-fill,var(--accent));transition:width .1s;}
.bluf{background:linear-gradient(135deg,rgba(201,169,110,.10),rgba(201,169,110,.03));border-left:3px solid var(--accent);border-radius:0 var(--radius) var(--radius) 0;padding:1.25rem 1.5rem;margin:1.5rem 0;}
.bluf-title{font-family:var(--mono);font-size:.7rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--accent-hover);margin-bottom:.5rem;}
.bluf-list{margin:0;padding-left:1.1rem;line-height:1.6;}
.stat-strip{display:flex;flex-wrap:wrap;gap:.75rem;margin:1.5rem 0;}
.stat-cell{flex:1 1 140px;background:var(--cream);border:1px solid var(--border);border-radius:var(--radius);padding:.85rem 1rem;}
.stat-num{font-family:var(--mono);font-size:1.4rem;font-weight:700;color:var(--accent-hover);}
.stat-label{font-size:.78rem;color:var(--text-light);margin-top:.2rem;}
.mobile-toc{margin:1.25rem 0;border:1px solid var(--border);border-radius:var(--radius);padding:.5rem 1rem;background:var(--cream);}
.mobile-toc summary{font-family:var(--mono);font-size:.78rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;color:var(--accent-hover);}
.mobile-toc ol{margin:.6rem 0 .2rem;padding-left:1.2rem;line-height:1.7;}
.mobile-toc a{color:var(--text);text-decoration:none;}
@media(min-width:1281px){.mobile-toc{display:none;}}
.chapter-rail{position:fixed;top:50%;right:1.5rem;transform:translateY(-50%);width:220px;max-height:70vh;overflow-y:auto;font-size:.8125rem;z-index:50;padding:.75rem 0;border-left:2px solid var(--border);}
.chapter-rail-title{font-family:var(--mono);font-size:.6875rem;text-transform:uppercase;letter-spacing:.1em;color:var(--text-light);padding:0 1rem .5rem;}
.chapter-rail-list{list-style:none;padding:0;margin:0;}
.chapter-rail-list a{display:block;padding:.375rem 1rem;color:var(--text-light);text-decoration:none;border-left:2px solid transparent;margin-left:-2px;transition:all .15s;line-height:1.4;}
.chapter-rail-list a:hover{color:var(--dark);}
.chapter-rail-list a.active{color:var(--accent-hover);border-left-color:var(--accent);font-weight:600;}
@media(max-width:1280px){.chapter-rail{display:none;}}
.glossary{border-bottom:1px dotted var(--accent-hover);cursor:help;}
.verified-date{display:inline-block;margin-left:.35em;padding:.05em .4em;font-family:var(--mono);font-size:.72em;color:#6b7280;background:#f0ece2;border-radius:3px;vertical-align:baseline;white-space:nowrap;}
.qa-inline{position:relative;background:linear-gradient(135deg,rgba(201,169,110,.08),rgba(201,169,110,.02));border-left:3px solid var(--accent);border-radius:0 var(--radius) var(--radius) 0;padding:1.25rem 1.5rem 1.25rem 3.25rem;margin:2rem 0;}
.qa-inline .qa-badge{position:absolute;top:1.25rem;left:1rem;width:1.75rem;height:1.75rem;display:flex;align-items:center;justify-content:center;font-family:var(--mono);font-weight:700;font-size:.875rem;background:var(--accent-fill,var(--accent));color:#fff;border-radius:50%;}
.qa-inline .qa-question{margin:0 0 .5rem;font-family:var(--display);font-size:1.0625rem;font-weight:600;line-height:1.35;}
.qa-inline .qa-answer{margin:0;line-height:1.55;font-size:.9375rem;}
table.data-table{width:100%;border-collapse:collapse;margin:1.5rem 0;font-size:.9rem;}
table.data-table th,table.data-table td{border:1px solid var(--border);padding:.6rem .7rem;text-align:left;}
table.data-table thead th{position:sticky;top:56px;background:var(--dark);color:#f5efe2;z-index:5;font-family:var(--mono);font-size:.78rem;letter-spacing:.04em;}
/* ZEBRA STRIPE, SURFACE-RELATIVE. Was var(--cream) (#f5efe2), a colour named for its VALUE. filmfont-extras.js injects td{color:#e6dec9} for the DARK article theme, so a cream stripe met cream text at 1.17:1 and 12 rows of the licence table were invisible. Two stylesheets, two theme assumptions, one table. currentColor at 6% is a MODULATION OF THE SURFACE: it darkens a light ground and lightens a dark one, and can never equal the text colour it is derived from. */
table.data-table tbody tr:nth-child(even){background:color-mix(in srgb,currentColor 6%,transparent);}
table.data-table tbody td:first-child{font-weight:600;}
.callout{background:var(--cream);border-left:3px solid var(--accent);border-radius:0 var(--radius) var(--radius) 0;padding:1rem 1.25rem;margin:1.5rem 0;}
.cta-block{background:linear-gradient(135deg,#15110c,#0e0c0a);color:#f5efe2;border-radius:var(--radius);padding:1.5rem;margin:2rem 0;text-align:center;}
.cta-block a{display:inline-block;margin-top:.75rem;background:var(--accent-fill,var(--accent));color:#0e0c0a;font-weight:700;text-decoration:none;padding:.6rem 1.3rem;border-radius:var(--radius);}
.read-next{margin:3rem 0;padding:2rem 0;border-top:1px solid var(--border);}
.read-next>h2{font-family:var(--display);font-size:1.5rem;margin:0 0 1.5rem;}
.read-next-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1rem;}
.read-next-card{display:block;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:1.25rem;text-decoration:none;color:inherit;transition:transform .15s,border-color .15s;}
.read-next-card:hover{transform:translateY(-2px);border-color:var(--accent);}
.read-next-chip{display:inline-block;font-family:var(--mono);font-size:.65rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;background:var(--cream);color:var(--text-light);padding:.2rem .55rem;border-radius:4px;margin-bottom:.75rem;}
.read-next-chip-cross{background:var(--accent-fill,var(--accent));color:#0e0c0a;}
.read-next-title{font-family:var(--display);font-size:1.05rem;font-weight:600;margin:0 0 .5rem;line-height:1.3;}
.read-next-desc{margin:0 0 .875rem;font-size:.85rem;color:var(--text-light);line-height:1.5;}
.read-next-meta{display:flex;justify-content:space-between;font-family:var(--mono);font-size:.72rem;color:var(--text-light);}
.read-next-arrow{color:var(--accent-hover);font-weight:600;text-transform:uppercase;letter-spacing:.08em;}
.citations{font-size:.85rem;line-height:1.6;color:var(--text-light);}
.freshness-pills{display:flex;flex-wrap:wrap;gap:.5rem;margin:.5rem 0 1rem;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.75rem}
.freshness-pills .pill{padding:.2rem .55rem;border-radius:999px;background:#f3f4f6;color:#374151;border:1px solid #e5e7eb}
.freshness-pills .pill-reviewed{background:#ecfdf5;color:#047857;border-color:#a7f3d0}
.freshness-pills .pill-due{background:#fef3c7;color:#92400e;border-color:#fde68a}

/* ── .qbar : QUANTITY BAR (2026-08-27) ─────────────────────────────────────────────────────────
 * INFORMATION-DESIGN STANDARD §1: any quantity that exists to be compared must be rendered
 * SPATIALLY. The licence census shipped with a category table (95 / 26 / 13 / 8 / 7 fonts) and a
 * licence split (147 / 1 / 1) entirely in text, which is the finding TOLD rather than SEEN.
 * §3.1 no invented palette: colours resolve to filmfont's own tokens.
 * §3.2 colour never carries meaning alone: the value is printed beside every bar.
 * §4   ZERO LOOKS LIKE ZERO: no min-width, no border on the fill, so nothing draws nothing.
 *      A count of 1 against 147 draws a genuine sliver, which is the honest encoding of 0.7%.
 */
.qbar{display:block;height:8px;border-radius:99px;background:var(--border);overflow:hidden;min-width:56px}
.qbar>i{display:block;height:100%;border-radius:99px;background:linear-gradient(90deg,var(--accent-hover),var(--accent))}
.qbar-row{display:flex;align-items:center;gap:.6rem}
.qbar-val{font-family:var(--mono);font-size:.82rem;font-variant-numeric:tabular-nums;color:var(--text);min-width:3em;text-align:right}
@media (prefers-reduced-motion:no-preference){.qbar>i{animation:qbarGrow .9s cubic-bezier(.2,.8,.2,1) both}}
@keyframes qbarGrow{from{width:0}}
.lic-fig{margin:1.6rem 0;padding:1.1rem 1.2rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--cream)}
.lic-t{font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--accent-hover);margin:0 0 .8rem}
.lic-row{margin:.45rem 0}
.lic-name{font-size:.84rem;color:var(--text);width:7.5em;flex:none}
.lic-c{margin:.9rem 0 0;font-size:.84rem;color:var(--text-light);line-height:1.55}

/* ── IX COMPONENT SET, filmfont tokens (2026-08-27) ────────────────────────────────────────────
 * INFORMATION-DESIGN §2. Added after the licence census measured 82% prose with four tables:
 * §1 was satisfied and the page still narrated most of its findings. Each component below answers a
 * different named failure; a component that answers none gets deleted (.ix-scan, four hours).
 */
.ix-box{display:grid;grid-template-columns:1fr 1fr;gap:0;margin:1.6rem 0;border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;background:#fff}
.ix-box .pane{padding:1.15rem 1.25rem;min-width:0}
.ix-box .pane+.pane{border-left:1px solid var(--border)}
.ix-box .ph{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;margin:0 0 .35rem;color:var(--accent-hover)}
.ix-box .big{font-family:var(--display);font-weight:700;font-size:1.4rem;margin:.1rem 0 .45rem;color:var(--text)}
.ix-box .sub{font-size:.84rem;color:var(--text-light);margin:0 0 .6rem;line-height:1.5}
.ix-box ul{margin:0;padding-left:1.05rem;font-size:.86rem;line-height:1.7}
.ix-box figcaption{grid-column:1/-1;font-size:.79rem;color:var(--text-light);line-height:1.55;padding:.8rem 1.25rem;background:var(--cream);border-top:1px solid var(--border)}
.ix-box .pane.unknown{background:repeating-linear-gradient(45deg,var(--cream),var(--cream) 6px,#fff 6px,#fff 12px)}
@media(max-width:640px){.ix-box{grid-template-columns:1fr}.ix-box .pane+.pane{border-left:0;border-top:1px solid var(--border)}}

.ix-triage{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:.75rem;margin:1.6rem 0;padding:0;list-style:none}
.ix-triage li{background:#fff;border:1px solid var(--border);border-top:3px solid var(--accent);border-radius:10px;padding:1rem 1.05rem}
.ix-triage .k{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--accent-hover);display:block;margin-bottom:.35rem}
.ix-triage .d{font-weight:700;font-size:.95rem;margin:0 0 .35rem;line-height:1.35}
.ix-triage .w{font-size:.85rem;color:var(--text-light);margin:0;line-height:1.55}

.ix-limits{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:.7rem;margin:1.5rem 0}
.ix-limits div{background:var(--cream);border-left:3px solid var(--border);border-radius:0 8px 8px 0;padding:.85rem 1rem}
.ix-limits b{display:block;font-size:.88rem;margin-bottom:.25rem}
.ix-limits span{font-size:.83rem;color:var(--text-light);line-height:1.55}

/* ── LIGHT-SURFACE TEXT COLOUR (2026-08-27) ────────────────────────────────────────────────────
 * ⛔ INFORMATION-DESIGN §4: A COLOUR TOKEN IS NOT VERIFIED UNTIL MEASURED ON THE SURFACE IT LANDS ON.
 *   filmfont articles render light text on a dark page. Every component that paints its own LIGHT
 *   background therefore inverts the assumption, and any text inside it that INHERITS colour comes
 *   out light-on-light. Measured on the live census page:
 *       .ix-limits b   1.00:1   (cream on cream, literally invisible)
 *       .ix-box li     1.15:1
 *       .pull-quote p  1.17:1   <- PRE-EXISTING, affects every article using it
 *       .ix-triage .d  1.34:1
 *   The tell: every element with an EXPLICIT token (--text-light, 5.2 to 6.0) passed, and every
 *   element that inherited failed. Inheritance is the bug, not the palette.
 * ⭐ A component that paints a background must also state its foreground. Half a colour pair is a
 *   guess about whatever it lands on.
 */
.ix-box li,.ix-box ul{color:var(--text)}
.ix-triage .d{color:var(--text)}
.ix-limits b{color:var(--text)}
.pull-quote p{color:var(--text)}
.pull-quote{color:var(--text)}

/* ── DARK CHROME OVERRIDE ────────────────────────────────────────────────────────────────────
   ⛔ site_engine.js injects `.nav-left a{color:var(--text-light,#a1a1aa)}` at RUNTIME, so it
   lands after this file and wins on equal specificity. On filmfont --text-light is #6b6256, a
   LIGHT-GROUND token, and the article pages render on #0e0c0a: measured 3.26, below AA, on
   every article. filmfont-extras.js already sets the correct #a89d85 and loses the same race.
   ⭐ The token is NOT the bug. This file also paints a dozen cream and white cards, where
   --text/--text-light are exactly right. Only the DARK chrome is wrong, so only it is overridden,
   at #site-header specificity so a later runtime injection cannot outrank it. */
/* ⭐⭐ WAS A HARDCODED #a89d85 — THE DARK-GROUND VALUE, ON A SELECTOR THAT MATCHES BOTH GROUNDS.
   The note above reasons correctly about DARK chrome and the selector never said dark: measured
   live, ALL 8 shipped pages carry #site-header, light and dark alike, so this painted a dark-theme
   tan onto light pages at 2.57:1. I confirmed the opposite from a STALE LOCAL glossary.html that
   still said `<header class="arc-hero">`; the shipped page disagrees.
   ⭐⭐⭐ THE GROUND IS NOW DECLARED RATHER THAN INFERRED. `site_engine.js` — the only asset that
     reaches all 195 pages — injects `:root{--text-light:#78716c}` with
     `body.lattice-dark{--text-light:#a89d85}`, and `tools/visual-audit/ground-marker.mjs` stamps
     that marker from the page's MEASURED background, so the marker cannot disagree with reality.
     Run it with --check as a gate; that is the half that stops this recurring.
   ⚠️ The specificity is kept deliberately. It is no longer needed to win a value argument, but it
     still beats the engine's runtime `.nav-left a`, so the rule stays predictable if the engine
     changes underneath it. It now carries a TOKEN, so winning costs nothing. */
#site-header .nav-left a { color: var(--text-light); }
#site-header .nav-left a:hover { color: #c9a96e; }
