/*! hero.css — motion and micro-interaction layer for the AIMS product pages.
    Pairs with hero.js. Every animation is disabled under prefers-reduced-motion. */

/* Headline lines wipe up from a mask, rather than fading — it reads as
   deliberate typesetting instead of a generic fade-in. */
.hx-l { display: block; overflow: hidden; }
.hx-i {
  display: block;
  transform: translateY(112%);
  animation: hxLine 0.85s cubic-bezier(0.22, 0.8, 0.24, 1) forwards;
}
@keyframes hxLine { to { transform: translateY(0); } }

.hx-fade { opacity: 0; animation: hxFade 0.7s cubic-bezier(0.22, 0.8, 0.24, 1) forwards; }
@keyframes hxFade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* Sections lift into place on scroll.
   Only ever applied by hero.js — if the script never runs, nothing is hidden.
   hero.js also force-reveals everything after 2.2s as a second guarantee. */
.hx-rise {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s cubic-bezier(0.22, 0.8, 0.24, 1),
              transform 0.6s cubic-bezier(0.22, 0.8, 0.24, 1);
}
.hx-in { opacity: 1; transform: none; }

/* Cards get a real hover: lift, a warmer border, and a shadow that implies
   depth rather than a flat outline swap. */
.c, .stat, .step {
  transition: transform 0.24s cubic-bezier(0.22, 0.8, 0.24, 1),
              box-shadow 0.24s, border-color 0.24s;
}
.c:hover, .stat:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 34px -18px rgba(0, 0, 0, 0.32);
}

/* Buttons: a light sweep on hover, and a real press. */
.btn { position: relative; overflow: hidden; }
.btn::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,0.28) 50%, transparent 70%);
  transform: translateX(-120%);
  transition: transform 0.6s cubic-bezier(0.22, 0.8, 0.24, 1);
  pointer-events: none;
}
.btn:hover::after { transform: translateX(120%); }
.btn:active { transform: translateY(1px) scale(0.995); }

/* Inputs shouldn't just change border colour — give focus a soft halo. */
input, textarea, select { transition: border-color 0.2s, box-shadow 0.2s, background 0.2s; }
input:focus, textarea:focus, select:focus { box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.12); }

/* The working state should feel alive rather than frozen. */
.btn[disabled] { position: relative; }
.btn[disabled]::before {
  content: ""; position: absolute; left: 0; bottom: 0; height: 2px; width: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.85), transparent);
  animation: hxBar 1.1s linear infinite;
}
@keyframes hxBar { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

/* Results arriving should be noticed. */
.out[style*="block"] > *, .quote, .lesson { animation: hxPop 0.5s cubic-bezier(0.22, 0.8, 0.24, 1); }
@keyframes hxPop { from { opacity: 0; transform: translateY(12px) scale(0.995); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .hx-i, .hx-fade, .hx-rise, .hx-in,
  .out[style*="block"] > *, .quote, .lesson { animation: none !important; transition: none !important;
    opacity: 1 !important; transform: none !important; }
  .btn::after, .btn[disabled]::before { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   ARCHETYPES & LAYOUTS  (Luis, 2026-08-22: "they look the same, cookie-cutter")
   ──────────────────────────────────────────────────────────────────────────
   The tint was never the problem: 114 of 151 apps shipped the identical
   section order (header → tool → why → how → pricing → footer). Because those
   six are *direct children of <body>*, order is changeable in CSS alone — no
   page regeneration, no markup edit.

     <body data-theme="editorial" data-layout="story">

   data-layout  section order + hero composition   story · tool · split · proof
   data-theme   type, shape, density, palette use  editorial · console · warm ·
                                                   poster · clinical · cabin

   Both are additive: a page with neither attribute renders exactly as before.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Layout: section order ────────────────────────────────────────────── */
/* Numbered in tens so a lane's extra sections slot in without renumbering.
   Anything not named here lands at 60 - after the plans, before the footer -
   rather than order:0, which floats it ABOVE the header. That is exactly what
   the Compare lane's #compare section did before this rule existed. */
body[data-layout] { display: flex; flex-direction: column; }
body[data-layout] > *        { order: 60; }
body[data-layout] > header   { order: 10; }
body[data-layout] > nav[data-jump] { order: 15; }  /* directly under the hero */
body[data-layout] > section[data-related] { order: 80; }  /* last, before the footer */
body[data-layout] > #tool    { order: 20; }
body[data-layout] > #compare { order: 25; }  /* Compare lane: travels with the tool */
body[data-layout] > #why     { order: 30; }
body[data-layout] > #better  { order: 35; }  /* Lang lane */
body[data-layout] > #how     { order: 40; }
body[data-layout] > #pricing { order: 50; }
body[data-layout] > footer   { order: 90; }

/* Editorial and console take no hero photo (ART-DIRECTION). Both paint their own
   header ground — console a dark #0d1117 chrome with light text — and a page's
   inline `header::before` photo scrim renders ABOVE that ground, which put white
   text on a pale photo on every console app. Suppress the photo layer for both. */
body[data-theme="console"] > header::before,
body[data-theme="editorial"] > header::before { display: none; }

/* story — hero → why it exists → form → how → plans. The case is made before
   the ask, for products people are wary of. */
body[data-layout="story"] > #why  { order: 20; }
body[data-layout="story"] > #tool { order: 25; }

/* tool — the tool IS the page. The hero collapses to a slim band and the form
   sits at the fold; the pitch moves below it. The two hero buttons are dropped
   because both scrolled to a form that is now already on screen. */
body[data-layout="tool"] > #pricing { order: 30; }
body[data-layout="tool"] > #why     { order: 40; }
body[data-layout="tool"] > #how     { order: 50; }
body[data-layout="tool"] > header { min-height: 0; padding-block: clamp(12px, 2.6vw, 24px); }
/* !important is load-bearing: hero.js and hero3d.js both set the canvas up with
   an inline `cssText` containing display:block, and an inline declaration beats a
   stylesheet rule. Without it the hero canvas kept rendering in the tool layout
   (reported by v22's browser check, 2026-08-23). Covers both engines. */
body[data-layout="tool"] > header canvas { display: none !important; }
body[data-layout="tool"] > header .cta   { display: none; }
/* Slim, not shrunken. The first pass took the headline down to 21-32px, which
   read as a page that had lost its title rather than one that gets to the tool
   fast (Luis, 2026-08-23: "hero headline too small"). This keeps the compact
   band but gives the headline back its authority. */
body[data-layout="tool"] > header h1 { font-size: clamp(28px, 4.4vw, 46px); margin: 0 0 8px; }
body[data-layout="tool"] > header .lede { font-size: 0.98rem; max-width: 62ch; margin-bottom: 10px; }
body[data-layout="tool"] > #tool { padding-top: 0; }

/* proof — the numbers carry the page: stats strip, then the form, then plans.
   #why is re-cut as a horizontal band instead of a three-card grid. */
body[data-layout="proof"] > #why     { order: 20; }
body[data-layout="proof"] > #tool    { order: 25; }
body[data-layout="proof"] > #pricing { order: 40; }
body[data-layout="proof"] > #how     { order: 50; }
body[data-layout="proof"] > #why { padding-block: clamp(18px, 3vw, 30px); }
body[data-layout="proof"] > #why .stats { display: flex; flex-wrap: wrap; gap: clamp(14px, 3vw, 34px); }
body[data-layout="proof"] > #why .stats .stat { flex: 1 1 150px; background: none; border: 0; padding: 0; }
body[data-layout="proof"] > #why > .wrap > h2 { font-size: clamp(19px, 2.4vw, 26px); }

/* split — hero and form share the fold, then plans, then the argument.
   Grid placement on <body>; single column below 900px so nothing is cramped. */
@media (min-width: 900px) {
  body[data-layout="split"] {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    align-items: start;
  }
  body[data-layout="split"] > header   { grid-area: 1 / 1; }
  body[data-layout="split"] > #tool    { grid-area: 1 / 2; padding-top: clamp(30px, 5vw, 72px); }
  /* The jump bar spans both columns under the fold — it is a body child, so
     without an explicit row the grid would drop it into the hero column. */
  body[data-layout="split"] > nav[data-jump]        { grid-area: 2 / 1 / auto / -1; }
  body[data-layout="split"] > #pricing              { grid-area: 3 / 1 / auto / -1; }
  body[data-layout="split"] > #why                  { grid-area: 4 / 1 / auto / -1; }
  body[data-layout="split"] > #how                  { grid-area: 5 / 1 / auto / -1; }
  body[data-layout="split"] > section[data-related] { grid-area: 6 / 1 / auto / -1; }
  body[data-layout="split"] > footer                { grid-area: 7 / 1 / auto / -1; }
  /* Each half is its own column, so the shared 1040px measure must relax. */
  body[data-layout="split"] > header > .wrap,
  body[data-layout="split"] > #tool  > .wrap { max-width: none; }
  body[data-layout="split"] > header .lede { max-width: 46ch; }
}

/* ── Archetype: editorial ─────────────────────────────────────────────────
   Civic and legal letters. A broadsheet: serif throughout, hairline rules,
   square corners, small-caps labels, no rounded softness anywhere. */
body[data-theme="editorial"] {
  --disp: "Fraunces", "Iowan Old Style", Georgia, serif;
  --sans: "Newsreader", Georgia, "Times New Roman", serif;
  line-height: 1.58;
}
body[data-theme="editorial"] .panel,
body[data-theme="editorial"] .stat,
body[data-theme="editorial"] .step,
body[data-theme="editorial"] .plan,
body[data-theme="editorial"] input,
body[data-theme="editorial"] select,
body[data-theme="editorial"] textarea { border-radius: 0; }
body[data-theme="editorial"] .btn { border-radius: 0; letter-spacing: .01em; }
body[data-theme="editorial"] .badge {
  border-radius: 0; border-left: 2px solid var(--acc); background: none;
  text-transform: uppercase; letter-spacing: .09em; font-size: .68rem;
}
body[data-theme="editorial"] .eyebrow {
  text-transform: uppercase; letter-spacing: .16em; font-size: .66rem;
  font-family: var(--sans);
}
body[data-theme="editorial"] h1 { letter-spacing: -.018em; line-height: 1.06; }
body[data-theme="editorial"] .stats { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
body[data-theme="editorial"] .stat { background: none; border: 0; border-right: 1px solid var(--line); }
body[data-theme="editorial"] .stat:last-child { border-right: 0; }
body[data-theme="editorial"] .step { background: none; border: 0; border-top: 2px solid var(--ink); padding-top: 12px; }
body[data-theme="editorial"] .step .n { font-family: var(--sans); font-size: .72rem; letter-spacing: .12em; }
body[data-theme="editorial"] .plan { border: 1px solid var(--ink); box-shadow: none; }

/* ── Archetype: console ───────────────────────────────────────────────────
   Business, Money, Work, HOA boards. An instrument panel: geometric sans,
   monospace for every number and label, 2px corners, dark chrome header. */
body[data-theme="console"] {
  --disp: "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
  --sans: "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", monospace;
}
body[data-theme="console"] .panel,
body[data-theme="console"] .stat,
body[data-theme="console"] .step,
body[data-theme="console"] .plan,
body[data-theme="console"] .btn,
body[data-theme="console"] input,
body[data-theme="console"] select,
body[data-theme="console"] textarea { border-radius: 2px; }
body[data-theme="console"] > header { background: #0d1117; color: #e6edf3; }
body[data-theme="console"] > header h1,
body[data-theme="console"] > header .lede,
body[data-theme="console"] > header .brand { color: #e6edf3; }
body[data-theme="console"] > header .brand small { color: #8b949e; }
/* The console header is dark chrome, but the ghost button and the region pill
   kept the light-page ink and landed at 1.09:1 against it — invisible, and a
   WCAG failure on an actual control. Recolour everything that sits ON the dark
   header, not just the headline. */
body[data-theme="console"] > header .btn-g {
  color: #e6edf3; border-color: rgba(255, 255, 255, .30); background: transparent;
}
body[data-theme="console"] > header .btn-g:hover { background: rgba(255, 255, 255, .08); }
body[data-theme="console"] > header .fl,
body[data-theme="console"] > header .lede { color: #c9d1d9; }
body[data-theme="console"] .badge {
  border-radius: 2px; font-family: var(--mono); font-size: .68rem;
  background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.16); color: #c9d1d9;
}
body[data-theme="console"] .eyebrow,
body[data-theme="console"] .stat .n,
body[data-theme="console"] .pp,
body[data-theme="console"] .pn,
body[data-theme="console"] .step .n { font-family: var(--mono); letter-spacing: -.01em; }
body[data-theme="console"] .stats { gap: 1px; background: var(--line); border: 1px solid var(--line); }
body[data-theme="console"] .stat { background: var(--panel); border: 0; }
body[data-theme="console"] .step { border-left: 2px solid var(--acc); background: none; border-radius: 0; }
body[data-theme="console"] .step .n::before { content: "▸ "; color: var(--acc); }
body[data-theme="console"] h1 { letter-spacing: -.03em; }

/* ── Archetype: warm ──────────────────────────────────────────────────────
   Seniors, caregivers, health. Large humanist type, generous air, pill
   shapes, soft shadows. Nothing sharp, nothing small. */
body[data-theme="warm"] {
  --disp: "Atkinson Hyperlegible", ui-sans-serif, system-ui, sans-serif;
  --sans: "Atkinson Hyperlegible", ui-sans-serif, system-ui, sans-serif;
  font-size: 18px; line-height: 1.75;
}
body[data-theme="warm"] .panel,
body[data-theme="warm"] .stat,
body[data-theme="warm"] .step,
body[data-theme="warm"] .plan { border-radius: 22px; box-shadow: 0 10px 30px rgba(0,0,0,.07); }
body[data-theme="warm"] .btn,
body[data-theme="warm"] input,
body[data-theme="warm"] select { border-radius: 999px; }
body[data-theme="warm"] textarea { border-radius: 18px; }
body[data-theme="warm"] .btn-p { padding: 16px 30px; font-size: 1.06rem; }
body[data-theme="warm"] .badge { border-radius: 999px; font-size: .8rem; padding: 7px 15px; }
body[data-theme="warm"] section { padding-block: clamp(40px, 7vw, 92px); }
body[data-theme="warm"] .stat .n { font-size: clamp(30px, 5vw, 46px); }
body[data-theme="warm"] .step { text-align: center; }
body[data-theme="warm"] .step .n {
  display: inline-grid; place-items: center; width: 46px; height: 46px;
  border-radius: 999px; background: var(--acc); color: var(--accInk, #fff); margin-bottom: 8px;
}
body[data-theme="warm"] h1 { line-height: 1.16; }

/* ── Archetype: poster ────────────────────────────────────────────────────
   Compare and Lang. Loud: condensed display, hard offset shadows, rotated
   tags, blocks that overlap rather than sit in a tidy grid. */
body[data-theme="poster"] {
  --disp: "Archivo Black", "Barlow Condensed", Impact, sans-serif;
  --sans: "Inter", ui-sans-serif, system-ui, sans-serif;
}
body[data-theme="poster"] h1 { text-transform: uppercase; letter-spacing: -.022em; line-height: .98; }
body[data-theme="poster"] .panel,
body[data-theme="poster"] .stat,
body[data-theme="poster"] .step,
body[data-theme="poster"] .plan {
  border-radius: 4px; border: 2px solid var(--ink); box-shadow: 7px 7px 0 var(--ink);
}
body[data-theme="poster"] .btn { border-radius: 4px; border: 2px solid var(--ink); box-shadow: 4px 4px 0 var(--ink); font-weight: 800; }
body[data-theme="poster"] .btn:active { transform: translate(3px, 3px); box-shadow: 1px 1px 0 var(--ink); }
body[data-theme="poster"] .badge {
  border-radius: 3px; border: 2px solid var(--ink); background: var(--acc); color: var(--accInk, #fff);
  font-weight: 700; text-transform: uppercase; letter-spacing: .05em; font-size: .7rem;
}
body[data-theme="poster"] .badges .badge:nth-child(odd) { transform: rotate(-1.6deg); }
body[data-theme="poster"] .badges .badge:nth-child(even) { transform: rotate(1.4deg); }
body[data-theme="poster"] .plan.hot { transform: rotate(-1deg); }
body[data-theme="poster"] .stat .n { font-family: var(--disp); font-size: clamp(32px, 6vw, 56px); }
body[data-theme="poster"] .eyebrow { text-transform: uppercase; letter-spacing: .1em; font-weight: 800; }

/* ── Archetype: clinical ──────────────────────────────────────────────────
   Health costs, insurance, benefits. Calm and exact: neutral sans, 1px
   borders, white surfaces, no shadow, a vertical stepper. */
body[data-theme="clinical"] {
  --disp: "Inter", ui-sans-serif, system-ui, sans-serif;
  --sans: "Inter", ui-sans-serif, system-ui, sans-serif;
  line-height: 1.62;
}
body[data-theme="clinical"] .panel,
body[data-theme="clinical"] .stat,
body[data-theme="clinical"] .step,
body[data-theme="clinical"] .plan {
  border-radius: 6px; border: 1px solid var(--line); box-shadow: none; background: var(--panel, #fff);
}
body[data-theme="clinical"] .btn { border-radius: 6px; box-shadow: none; }
body[data-theme="clinical"] .badge { border-radius: 4px; background: none; border: 1px solid var(--line); font-size: .72rem; }
body[data-theme="clinical"] h1 { letter-spacing: -.028em; font-weight: 700; line-height: 1.12; }
body[data-theme="clinical"] .steps { display: grid; gap: 0; }
body[data-theme="clinical"] .step {
  border: 0; border-left: 1px solid var(--line); border-radius: 0;
  padding: 0 0 26px 26px; margin-left: 12px; position: relative; background: none;
}
body[data-theme="clinical"] .step:last-child { border-left-color: transparent; padding-bottom: 0; }
body[data-theme="clinical"] .step .n {
  position: absolute; left: -11px; top: 0; width: 22px; height: 22px; border-radius: 999px;
  background: var(--panel, #fff); border: 1px solid var(--acc); color: var(--acc);
  display: grid; place-items: center; font-size: .7rem; font-weight: 700;
}
body[data-theme="clinical"] .stat { text-align: left; }

/* Reduced motion: the poster press-down is motion too. */
@media (prefers-reduced-motion: reduce) {
  body[data-theme="poster"] .btn:active { transform: none; }
  body[data-theme="poster"] .badges .badge,
  body[data-theme="poster"] .plan.hot { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   JUMP NAV + RELATED TOOLS
   Fleet audit 2026-08-23: 0 of 167 apps had a <nav>. Built by nav.js from the
   sections a page actually has; styled per archetype below so it reads as part
   of each design rather than a bolted-on bar.
   ══════════════════════════════════════════════════════════════════════════ */
nav[data-jump] {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 10px;
  padding: 8px clamp(14px, 4vw, 34px);
  background: color-mix(in srgb, var(--bg, #fff) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(9px);
  -webkit-backdrop-filter: saturate(1.4) blur(9px);
  border-bottom: 1px solid var(--line, #e5e0d6);
  overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
}
nav[data-jump]::-webkit-scrollbar { display: none; }
nav[data-jump] ul {
  display: flex; align-items: center; gap: 4px;
  list-style: none; margin: 0; padding: 0; flex: 1 1 auto;
}
nav[data-jump] a {
  display: block; white-space: nowrap; text-decoration: none;
  font-size: .82rem; line-height: 1; padding: 8px 12px;
  color: var(--mut, #66605a); border-radius: 999px;
}
nav[data-jump] a:hover { color: var(--ink, #1d1a17); background: var(--soft, #f2eee6); }
nav[data-jump] a:focus-visible { outline: 2px solid var(--acc, #1f5f3f); outline-offset: 2px; }
nav[data-jump] a[aria-current] { color: var(--ink, #1d1a17); background: var(--soft, #f2eee6); font-weight: 600; }
nav[data-jump] .jump-top {
  margin-left: auto; opacity: 0; pointer-events: none;
  transition: opacity .18s ease; font-variant-numeric: tabular-nums;
}
nav[data-jump].is-scrolled .jump-top { opacity: 1; pointer-events: auto; }
/* The sticky bar must not hide the heading you just jumped to. */
body > section[id] { scroll-margin-top: 58px; }

/* Archetype fits ------------------------------------------------------- */
body[data-theme="editorial"] nav[data-jump] { border-bottom-width: 2px; }
body[data-theme="editorial"] nav[data-jump] a {
  border-radius: 0; text-transform: uppercase; letter-spacing: .09em; font-size: .68rem;
}
body[data-theme="editorial"] nav[data-jump] a[aria-current] {
  background: none; box-shadow: inset 0 -2px 0 var(--acc, #1f5f3f);
}
body[data-theme="console"] nav[data-jump] {
  background: #0d1117; border-bottom-color: #1f2937;
}
body[data-theme="console"] nav[data-jump] a {
  border-radius: 2px; color: #8b949e;
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: .72rem;
}
body[data-theme="console"] nav[data-jump] a:hover,
body[data-theme="console"] nav[data-jump] a[aria-current] { color: #e6edf3; background: #161d27; }
body[data-theme="warm"] nav[data-jump] a { font-size: .92rem; padding: 10px 16px; }
body[data-theme="poster"] nav[data-jump] { border-bottom: 2px solid var(--ink, #1d1a17); }
body[data-theme="poster"] nav[data-jump] a {
  border-radius: 3px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; font-size: .72rem;
}
body[data-theme="poster"] nav[data-jump] a[aria-current] {
  background: var(--acc, #be123c); color: var(--accInk, #fff);
}
body[data-theme="clinical"] nav[data-jump] a { border-radius: 4px; font-size: .8rem; }
body[data-theme="cabin"] nav[data-jump] {
  background: rgba(11, 15, 20, .86); border-bottom-color: #1f2937;
}
body[data-theme="cabin"] nav[data-jump] a { color: #9aa3b2; }
body[data-theme="cabin"] nav[data-jump] a[aria-current] { color: #f3f4f6; background: #161d27; }

/* Related tools -------------------------------------------------------- */
section[data-related] { padding-block: clamp(30px, 5vw, 58px); }
section[data-related] h2 {
  font-size: clamp(17px, 2.1vw, 22px); margin: 0 0 4px;
}
section[data-related] .rel-sub { color: var(--mut, #66605a); font-size: .9rem; margin: 0 0 18px; }
section[data-related] .rel-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
section[data-related] a.rel {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--line, #e5e0d6); border-radius: 12px;
  padding: 14px 16px; background: var(--panel, #fff);
  transition: transform .16s ease, border-color .16s ease;
}
section[data-related] a.rel:hover { transform: translateY(-2px); border-color: var(--acc, #1f5f3f); }
section[data-related] a.rel:focus-visible { outline: 2px solid var(--acc, #1f5f3f); outline-offset: 2px; }
section[data-related] a.rel b { display: block; font-size: .98rem; margin-bottom: 3px; }
section[data-related] a.rel span { display: block; font-size: .82rem; color: var(--mut, #66605a); }
body[data-theme="editorial"] section[data-related] a.rel { border-radius: 0; }
body[data-theme="console"] section[data-related] a.rel { border-radius: 2px; }
body[data-theme="poster"] section[data-related] a.rel {
  border: 2px solid var(--ink, #1d1a17); border-radius: 4px; box-shadow: 5px 5px 0 var(--ink, #1d1a17);
}
body[data-theme="poster"] section[data-related] a.rel:hover { transform: translate(-2px, -2px); box-shadow: 7px 7px 0 var(--ink, #1d1a17); }
body[data-theme="warm"] section[data-related] a.rel { border-radius: 20px; box-shadow: 0 8px 24px rgba(0,0,0,.06); }

@media (prefers-reduced-motion: reduce) {
  section[data-related] a.rel { transition: none; }
  section[data-related] a.rel:hover { transform: none; }
  nav[data-jump] .jump-top { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE (390px sweep, 2026-08-23)
   A measured pass over all 177 apps at a true 390px viewport found two
   systemic defects. Both are fixed here rather than in 150 pages.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* 186 controls came in under 32px tall — "Try a sample" alone on 146 apps at
     26-27px. That is below any sane thumb target (WCAG 2.5.5 asks 44). Height
     is set, not padding, so it holds whatever the theme does to padding. */
  .btn {
    min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }
  /* "Try a sample" is <button class="sample"> with padding:0 — a text link, not
     a .btn, so the rule above misses it. It was the single most common defect in
     the sweep (146 apps at 26-27px). Grow the hit area with padding rather than a
     box, so it still reads as a link. The Lang lane uses the same trick with
     `button.lnk` (4 controls per app, 23-28px). `body` prefix is needed because the page's
     own `.sample{padding:0}` sits in a later <style> block at equal specificity. */
  body .sample, body button.sample,
  body .lnk, body button.lnk {
    min-height: 44px; padding: 11px 2px;
    display: inline-flex; align-items: center;
  }
  /* Seven Families headlines wrapped to 302-403px — most of a phone screen
     before a word of copy. Cap the display size on narrow screens; the desktop
     sizes are untouched. Placed after the layout rules so it wins on equal
     specificity. */
  body[data-layout] > header h1,
  body > header h1 { font-size: clamp(26px, 8vw, 40px); line-height: 1.12; }
  body[data-theme="poster"] > header h1 { font-size: clamp(24px, 7.4vw, 36px); }
}
