:root{
  /* One system (2026-09-09): navy ink, gold, and warm neutrals derived from the two. Body text is
     the ink lightened with almost no saturation; page-2, lines and chrome lean warm, toward the
     gold, never blue. Green and red exist only for the contact form's sent / failed alerts. */
  --bg:#ffffff; --bg-2:#f8f6f1; --panel:#ffffff; --nav-glass:rgba(255,255,255,.88); --hero-glow:#f7f1e4;
  --line:#e8e4dc; --line-2:#d8d2c6;
  --text:#0b1220; --muted:#4b4f5a; --dim:#686c77;
  --gold:#C8A56A; --gold-light:#E8D5AF; --gold-dark:#7A6138; --gold-soft:#f7f1e4;
  /* a third of the way from the panel to the soft gold: a card should warm, not light up */
  --tile-hover:#fcfaf6; --ink:#0B1220; --ink-2:#1c2740; --dark:#09111D;
  --gold-shade:linear-gradient(180deg,#F0DDA8 0%,#DDC183 40%,#C8A56A 62%,#B08D55 100%);
  --ok:#047857; --ok-soft:#ecfdf5; --red:#dc2626; --red-soft:#fef2f2;   /* form alerts only */
  /* A scrollbar is part of the page or it is the operating system showing through it. Warm
     neutral, low alpha, and a pair per theme so it is legible on either ground. */
  --scroll-thumb:rgba(26,22,15,.22); --scroll-thumb-hover:rgba(26,22,15,.4);
  --shadow-sm:0 1px 2px rgba(16,24,40,.06);
  --shadow:0 1px 2px rgba(16,24,40,.05),0 10px 30px -14px rgba(16,24,40,.16);
  --radius:14px; --max:1520px;
  --grad:linear-gradient(135deg,#C9A76B,#8A6B3B);
}
*{box-sizing:border-box}

/* Dark theme. A remembered choice (Shift+D) sets data-theme in the head before paint; with no
   choice the site is light (Michael, 2026-09-09: "default light mode").
   
   It used to be built ON NAVY, and that was the system contradicting itself. The light theme's
   own rule, four lines from the top of this file, is that "page-2, lines and chrome lean warm,
   toward the gold, never blue" - navy is the INK there (--text, --ink, --dark) and every surface
   is warm: --bg-2 #f8f6f1, --line #e8e4dc, --gold-soft #f7f1e4. Dark mode then set --bg to
   #09111D, which is --dark: it promoted the ink colour to be the surface, so the one thing the
   system says must never be blue became the largest blue area on the page. Gold on navy reads
   corporate; gold on a warm near-black reads expensive, which is the whole point of the palette
   (Michael, 2026-09-14: "the dark mode of our site has this blue feel going on. not proper dark
   mode and gold premium feel").
   
   The surfaces are NEUTRAL, not warm. Warming them was the first attempt and it overshot:
   #0E0D0B is only three points of spread and it still read brown across a whole page (Michael,
   2026-09-14: "closer just too brown feeling"). Any hue at all in a surface this large is
   visible, so the surfaces carry none, and the warmth lives where it belongs - in the gold, and
   in the cream text and muted tones that were already warm and are untouched (--text #F3EEE4,
   --muted #BAB5A9, --dim #948c7e). Black and gold, which is the pairing the palette was after.
   --ink is overridden too because in dark mode it is the TEXT ON the gold buttons, so leaving it
   navy put the blue straight back into the one element the eye goes to first. */
/* And the gold TINTS are mixed from --gold-light, not --gold. Gold at .14 over a near-black
   panel composites to rgb(49,44,35), which is not gold, it is mud: 14 points of channel spread
   on an area as big as the compare table's own row, or the hero's radial glow (Michael,
   2026-09-14: "in dark mode this light effect looks awful and brown ... on the compare page
   massive brown strip"). The light gold at a lower alpha lands at rgb(43,41,38) and rgb(27,26,23)
   instead: a lift you can see, with the hue too faint to read as brown. The tint is only ever
   scenery; the gold that has to LOOK gold is the solid --gold on buttons and --gold-dark on text,
   and neither is touched. */
:root[data-theme="dark"]{--bg:#0C0C0C; --bg-2:#141414; --panel:#181818; --nav-glass:rgba(12,12,12,.86); --ink:#121212; --hero-glow:rgba(232,213,175,.07); --line:rgba(255,255,255,.09); --line-2:rgba(255,255,255,.16); --text:#F3EEE4; --muted:#BAB5A9; --dim:#948c7e; --gold-soft:rgba(232,213,175,.09); --tile-hover:rgba(232,213,175,.05); --gold-dark:#DCBF82; --grad:linear-gradient(135deg,#EAD7A8,#C8A56A); --shadow-sm:0 1px 2px rgba(0,0,0,.45); --shadow:0 1px 2px rgba(0,0,0,.45),0 10px 30px -14px rgba(0,0,0,.7); --scroll-thumb:rgba(232,213,175,.24); --scroll-thumb-hover:rgba(232,213,175,.42)}
:root[data-theme="dark"] .btn-primary,:root[data-theme="dark"] .pill.ok,:root[data-theme="dark"] .step .n{background:var(--gold);color:var(--ink)}
:root[data-theme="dark"] .billing .thumb{background:var(--gold)}:root[data-theme="dark"] .billing button.on{color:var(--ink)}:root[data-theme="dark"] .tier-head .badge{background:var(--gold);color:var(--ink)}
:root[data-theme="dark"] .billing button.on span{color:var(--ink-2)}
:root[data-theme="dark"] .btn-primary:hover{background:var(--gold-light)}
:root[data-theme="dark"] .cta{border:1px solid var(--line)}
:root[data-theme="dark"] .menu-btn,:root[data-theme="dark"] .btn-ghost,:root[data-theme="dark"] .theme-btn{color:var(--text)}
:root[data-theme="dark"] .hero h1 .accent,
:root[data-theme="dark"] .sec-line .accent{color:var(--gold)}
:root[data-theme="dark"] input::placeholder,:root[data-theme="dark"] textarea::placeholder{color:var(--dim)}
/* the toggle: moon in light, sun in dark */
.theme-btn{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:10px;border:1px solid var(--line-2);background:var(--panel);color:var(--text);cursor:pointer;padding:0}
.theme-btn .ico-sun{display:none}
:root[data-theme="dark"] .theme-btn .ico-sun{display:block}:root[data-theme="dark"] .theme-btn .ico-moon{display:none}
/* The page's own colour, so a page shorter than the window ends in the page's colour, not in whatever
   was last painted on <html>: the head's pre-paint copy of this colour, which site.js takes off once
   this sheet is in (a stale navy there showed below short pages for weeks after the palette went
   black on 2026-09-14). */
html{scroll-behavior:smooth;scroll-padding-top:60px;background:var(--bg)}
body{margin:0;background:var(--bg);color:var(--text);font-family:"Plus Jakarta Sans",Inter,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:clip}
a{color:inherit;text-decoration:none}
/* No text highlighting across the site (Michael, 2026-09-09), except where a visitor needs to select
   or copy: form fields, the example addresses in code, and the email address. Images do not drag
   or throw up the long-press sheet. */
body{-webkit-user-select:none;user-select:none}
input,textarea,select,[contenteditable],code,a[href^="mailto:"],.alert{-webkit-user-select:text;user-select:text}
img{-webkit-user-drag:none;-webkit-touch-callout:none}
/* No grey/black tap flash on iOS (Michael, 2026-09-09: the logo "highlights with a black square"); keyboard focus keeps a ring. */
a,button,summary,label,select,[role=button]{-webkit-tap-highlight-color:transparent}
/* summary and label are the two tappable things here that are neither <a> nor <button>:
   the FAQ rows and the service chips. Left out, each shows the platform's grey tap box on
   a phone and nowhere else, so it is invisible on a desktop and invisible in a screenshot
   taken after the tap (Michael, 2026-09-14: "getting an odd highlight on the faq page ...
   also ... on the select which services you use"). */
/* No focus box on any link or button anywhere on the site (Michael, 2026-09-10: "stop that all over this site"); fields keep
   their ring because a cursor has to be visible when you type. */
a:focus,a:focus-visible,button:focus,button:focus-visible,summary:focus,summary:focus-visible,[role=button]:focus{outline:none;box-shadow:none}
img,svg{max-width:100%}
.wrap{max-width:var(--max);margin:0 auto;padding:0 24px}
/* At 1520 the page reaches the window edge on the two commonest laptop widths, a 1920 screen at
   125 percent scaling (1536) and a 14 inch MacBook (1512), where 24px of padding is all that
   stands between the text and the frame. Wider screens do not need it and do not notice it. */
@media (min-width:1100px){.wrap{padding:0 44px}}
h1,h2,h3{margin:0;letter-spacing:-.025em;line-height:1.1;color:var(--text)}
h1{font-size:clamp(2.2rem,5.2vw,3.9rem);font-weight:800}
h2{font-size:clamp(1.65rem,3.2vw,2.4rem);font-weight:800}
/* The two section lines, and they are a PAIR - the Why names the heap you are looking at,
   the Solution answers it in the same shape. Identical treatment on both, or the second
   stops reading as a reply to the first. Smaller and lighter than the About h2: it is a
   sentence introducing something, not a title competing with the hero. Capped in ch so it
   breaks somewhere sensible instead of running the full 1520px of the wrap. */
.sec-line{text-align:center;max-width:42ch;margin:0 auto 30px;
  font-size:clamp(1.61rem,2.8vw,2.17rem);font-weight:700;letter-spacing:-.01em;line-height:1.35}
/* 1.4x the original, 2026-09-26: first 1.5x ("the headers on each page need to be 1.5x bigger"),
   then "adjust to 1.4x bigger" the same day. Every term of the clamp is scaled - floor, slope and
   ceiling - so phones grow by the same factor as desktop. Was clamp(1.15rem,2vw,1.55rem). The hero
   h1 (clamp 2.2rem-3.9rem) still outranks it at every width. */
@media (max-width:640px){.sec-line{margin-bottom:22px}}
h3{font-size:1.05rem;font-weight:700;letter-spacing:-.01em}
p{margin:0}
.muted{color:var(--muted)}
.eyebrow{display:inline-flex;align-items:center;gap:8px;font-size:.76rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--gold-dark)}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:12px 20px;border-radius:10px;font-weight:700;font-size:.95rem;border:1px solid transparent;transition:background .15s ease,border-color .15s ease,box-shadow .15s ease,transform .18s ease;white-space:nowrap;cursor:pointer;font-family:inherit;line-height:1.2}
/* On anything with a real pointer, a button rises a touch under the cursor (Michael, 2026-09-09). */
@media (hover:hover){.btn:hover{transform:translateY(-2px)}.btn:active{transform:translateY(0)}}
.btn-primary{background:var(--ink);color:#fff;box-shadow:var(--shadow-sm)}
.btn-primary:hover{background:var(--ink-2)}
.btn-ghost{background:var(--panel);border-color:var(--line-2);color:var(--text);box-shadow:var(--shadow-sm)}
/* The Book-a-demo button: the mark's gold, shaded - lit from above, deeper at the foot - no texture
   (Michael, 2026-09-09: "No brushed just gold with shading please"). */
.btn-gold{color:var(--ink);background:var(--gold-shade);border-color:rgba(90,66,34,.5);box-shadow:inset 0 1px 0 rgba(255,255,255,.5),inset 0 -1px 0 rgba(0,0,0,.18),0 8px 18px rgba(122,97,56,.26);text-shadow:0 1px 0 rgba(255,248,230,.45)}
.btn-gold:hover{filter:brightness(1.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.55),inset 0 -1px 0 rgba(0,0,0,.18),0 10px 22px rgba(122,97,56,.32)}
.btn-gold:active{filter:brightness(.97)}
.btn-ghost:hover{border-color:var(--line-2);background:var(--bg-2)}
.btn[disabled]{opacity:.6;cursor:wait}
/* 48px from the bar to the content, everywhere (Michael, 2026-09-12: the compare spacing
   "needs to be the standard for all pages"). Plans and About stay tighter still at 32; they
   were already deliberately under the old 96 and raising them would be adding space back. */
section{padding:48px 0}
/* On a phone the top padding is the landing gap: a hash puts the section top under the sticky
   header, so whatever padding follows is empty screen before the first word. 64 and 52 read as a
   hole under the header (Michael, 2026-09-12). The bottom keeps its old value, so the break
   between two sections scrolling past is still clear. */
@media (max-width:720px){section{padding:24px 0 64px}html{scroll-padding-top:60px}}
.alt{background:linear-gradient(to bottom,var(--bg) 0%,var(--bg-2) 14%,var(--bg-2) 86%,var(--bg) 100%)}

/* nav */
.nav{position:sticky;top:0;z-index:50;background:var(--nav-glass);backdrop-filter:blur(12px);border-bottom:1px solid transparent;transition:border-color .3s ease}
.nav.scrolled,.nav.open{border-bottom-color:var(--line)}
/* The height is the logo plus the slack around it, and it is the slack that halves (Michael,
   2026-09-12). The logo is 34px here and 54px on a computer, so halving the bar itself would
   be shorter than the thing standing in it. 17px above and below, either way. */
.nav .wrap{display:flex;align-items:center;justify-content:space-between;height:52px;gap:16px}
/* The wordmark (Michael, 2026-09-10, from a spaced / premium sample): Montserrat, regular weight, uppercase, tracked a
   third of an em, a step larger against the mark than his sample. The trailing tracking is pulled back so the word
   ends where its last letter does. */
/* Tried on the mark's foot 2026-09-10 (baseline on its visible bottom, a .07em drop); Michael: "nope". Centred. */
.logo{display:flex;align-items:center;gap:9px;color:var(--text);line-height:1}
/* The wordmark (Michael, 2026-09-10): "Entertain" in the site face as it always was, heavy and tight; HQ as a
   bitmap in the mark's own two-tone brushed finish (docs/brand/mark/hq_finish.py), set from the same face at
   the same weight, so at .846em tall its capitals match the E exactly (cap height .757em, the Q's tail 10.5%
   of the bitmap below the baseline, which the translate puts back on the baseline). */
.logo .word{display:inline-flex;align-items:baseline;gap:.16em;font-family:"Plus Jakarta Sans",Inter,system-ui,sans-serif;font-weight:700;font-size:1.16rem;letter-spacing:-.03em;line-height:1;white-space:nowrap}
.logo .hq{display:block;height:.846em;width:auto;transform:translateY(10.5%)}
.logo .mark{width:34px;height:34px;flex-shrink:0;object-fit:contain}
.cta-mark{display:block;width:132px;height:132px;margin:0 auto 18px;object-fit:contain;filter:drop-shadow(0 12px 24px rgba(0,0,0,.45))}
.logo .hq{color:var(--gold)}
.nav-links{display:flex;gap:26px;font-size:.93rem;font-weight:600;color:var(--muted)}
.nav-links a{position:relative;padding:4px 0;transition:color .2s ease,transform .25s ease}
.nav-links a::after{content:"";position:absolute;left:0;right:0;bottom:-2px;height:1.5px;border-radius:2px;background:var(--grad);transform:scaleX(0);transform-origin:left;transition:transform .3s ease}
.nav-links a:hover{color:var(--text);transform:translateY(-2px)}
.nav-links a[aria-current]{color:var(--text)}
.nav-links a:hover::after,.nav-links a[aria-current]::after{transform:scaleX(1)}
.nav-cta{display:flex;align-items:center;gap:12px}
/* Desktop: the mark and the wordmark at double size in a taller bar (Michael, 2026-09-09: "try doubling it", then "decrease by 20%"). */
@media (min-width:861px){.nav .wrap{height:71px}.logo{gap:12px}.logo .word{font-size:1.85rem}.logo .mark{width:54px;height:54px}html{scroll-padding-top:79px}}
/* Desktop: the button group holds only the phone's menu button, so it leaves the bar entirely and the
   links sit at the right edge (Michael, 2026-09-09: "scooted to the right edge"). */
@media (min-width:861px){.nav-links{margin-left:auto}.nav-cta{display:none}}
/* Each named section is a page of its own on desktop (Michael, 2026-09-09: "when on the product page I
   should not see the what we solve page"): it fills the viewport below the 88px bar with its content
   centred, so the next section always starts below the fold and fades in when reached. The sub-parts
   of Plans and About (unnamed sections) stay attached to their page at natural height. */
@media (min-width:861px){/* Content starts at the padding and the leftover falls to the bottom. Centred, a section
   whose content does not fill a screen hands half the leftover back to the top, so its
   padding is not what you see and reducing it barely moves anything (Michael, 2026-09-12:
   the compare spacing is the standard now, and it cannot be if the centring overrides it). */
main > section.page{min-height:calc(100vh - 71px);display:flex;flex-direction:column;justify-content:flex-start;box-sizing:border-box}
  /* A wrap inside one of these flex pages keeps the page width: a flex item with auto side margins stops stretching and
     shrinks to its content, so the FAQ (short questions) came out narrower and centred while its neighbours reached the
     edges (Michael, 2026-09-10: "you cant have a pattern of fitting content to the width and then shrink and centre"). */
  main > section.page > .wrap{width:100%}
  /* The heap fills whatever the heading leaves. It was a hard 600px, which is a guess about a
     monitor: right on the laptop it was written on, 264px short of the section on a 2560 screen
     and 484px short on a 3440 one. A column that grows has no number in it to be wrong. */
  main > section#why.page > .wrap{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}
  /* The hero is the one section that centres rather than starting at its padding (Michael,
     2026-09-12): the opening screen sits in the middle of what is left under the bar. Its padding
     goes symmetric with it, because centring inside 48 top and 72 bottom is not centred, it is
     twelve pixels high, and the opening screen is where that shows. */
  main > section.hero.page{justify-content:center;padding-top:48px;padding-bottom:48px}
  /* Plans and About used to sit at 32 rather than the 48px standard, to compensate for what they
     carried above their content - Plans has a tab strip AND the billing switch. That reasoning
     predates the .sec-line headings: every section now OPENS with the same heading, so the thing
     directly under the bar is identical everywhere and the compensation only made the headings
     disagree with each other (Michael, 2026-09-13: "the padding between the nav bar and the top
     of the titles are not the same on each page. make the why page the standard padding"). The
     standard is section{padding:48px 0} and nothing overrides it now except the hero. */
}
/* The bar's links show focus through their underline, never a box. */
.nav-links a:focus{outline:none}.nav-links a:focus-visible::after{transform:scaleX(1)}
/* The logo never wears a focus box either (Michael, 2026-09-09: "weird highlight box"); keyboard focus underlines the wordmark in gold. */
.logo:focus{outline:none}.logo:focus-visible .word{text-decoration:underline;text-decoration-color:var(--gold);text-decoration-thickness:2px;text-underline-offset:5px}
/* No box around it, closed or open (Michael, 2026-09-12). What is left is the mark itself. */
.menu-btn{display:none;background:none;border:0;color:var(--text);padding:8px 6px;cursor:pointer;-webkit-tap-highlight-color:transparent}
.menu-btn .bar{display:block;width:22px;height:2px;border-radius:2px;background:currentColor;transform-origin:50% 50%}
.menu-btn .bar + .bar{margin-top:5px}
.mobile-only{display:none}
@media (max-width:860px){
  /* On phones the bar is FIXED and SOLID, never sticky-and-glass: iOS un-sticks a sticky bar inside
     a body that clips overflow and drops a backdrop-filter layer for a frame, so the bar vanished
     and came back and the page jumped with it (Michael, 2026-09-09; the app hit the same, LM-45).
     The page is padded under it; the hairline is a shadow so the height is exactly 60. */
  .nav{position:fixed;top:0;left:0;right:0;height:52px;background:var(--panel);backdrop-filter:none;-webkit-backdrop-filter:none;border-bottom:none;transition:box-shadow .3s ease}
  .nav.scrolled,.nav.open{box-shadow:0 1px 0 var(--line)}
  body{padding-top:52px}
  /* 44px of logo and a 44px button, so the slack is 16 and half of it is 8 (Michael,
     2026-09-12). 52px keeps both controls whole. */
  .nav .wrap{height:52px;gap:10px}
  .nav-cta{gap:8px}
  .theme-btn{width:38px;height:38px}
  .menu-btn{display:inline-flex;flex-direction:column;justify-content:center;align-items:center;padding:9px 11px;min-width:44px}
  /* The open menu is a full-height sheet: it covers the page (whose own Book-a-demo button sat
     right under the menu's - Michael, 2026-09-09: "two giant book a demo buttons right next to
     each other"), the links at the top, the demo button at the foot, the page locked behind it. */
  /* The sheet is always in the document, hidden by opacity and visibility, so opening and closing
     can ease (Michael, 2026-09-09: "right now it's just there and not there"): the sheet fades
     and settles down from 10px, the links follow it with a small stagger (timings +15%, Michael). */
  .nav-links{display:flex;flex-direction:column;position:fixed;left:0;right:0;top:52px;bottom:0;background:var(--panel);padding:4px 20px calc(24px + env(safe-area-inset-bottom,0px));gap:0;overflow-y:auto;overscroll-behavior:contain;opacity:0;visibility:hidden;transform:translateY(-10px);pointer-events:none;transition:opacity .25s ease,transform .3s ease,visibility 0s linear .3s}
  .nav.open .nav-links{opacity:1;visibility:visible;transform:none;pointer-events:auto;transition:opacity .25s ease,transform .3s ease,visibility 0s}
  .nav-links > *{opacity:0;transform:translateY(6px);transition:opacity .29s ease,transform .35s ease}
  .nav.open .nav-links > *{opacity:1;transform:none}
  .nav.open .nav-links > :nth-child(1){transition-delay:.035s}.nav.open .nav-links > :nth-child(2){transition-delay:.07s}.nav.open .nav-links > :nth-child(3){transition-delay:.105s}.nav.open .nav-links > :nth-child(4){transition-delay:.14s}.nav.open .nav-links > :nth-child(5){transition-delay:.175s}.nav.open .nav-links > :nth-child(6){transition-delay:.21s}.nav.open .nav-links > :nth-child(7){transition-delay:.245s}
  html:has(.nav.open){overflow:hidden}
  /* The morph. One phase on its own: the outer bars carry a move and a rotate at once, the middle
     one wipes out from its centre. */
  .menu-btn .bar{transition:transform .26s cubic-bezier(.2,.7,.2,1),opacity .16s ease,width .26s cubic-bezier(.2,.7,.2,1)}
  .nav.open .menu-btn .bar:nth-child(1){transform:translateY(7px) rotate(45deg)}
  .nav.open .menu-btn .bar:nth-child(2){opacity:0;width:0}
  .nav.open .menu-btn .bar:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

  /* Two phases where the browser can stagger a move against a rotate: slide together, then turn.
     Closing reverses it, turn back to flat and then slide apart, because the two states carry the
     delays the other way round. Delays rather than keyframes, so an interrupted press reverses from
     where it got to instead of jumping. */
  @supports (rotate:45deg){
    .menu-btn .bar{transform:none;translate:0 0;rotate:0deg;
      transition:rotate .19s cubic-bezier(.2,.7,.2,1),translate .23s cubic-bezier(.2,.7,.2,1) .15s,
                 opacity .16s ease .15s,width .2s cubic-bezier(.2,.7,.2,1) .15s}
    .nav.open .menu-btn .bar{transition:translate .19s cubic-bezier(.2,.7,.2,1),
                 rotate .23s cubic-bezier(.2,.7,.2,1) .15s,opacity .14s ease,width .18s cubic-bezier(.2,.7,.2,1)}
    .nav.open .menu-btn .bar:nth-child(1){transform:none;translate:0 7px;rotate:45deg}
    .nav.open .menu-btn .bar:nth-child(2){transform:none;opacity:0;width:0}
    .nav.open .menu-btn .bar:nth-child(3){transform:none;translate:0 -7px;rotate:-45deg}
  }
  .nav-links a{display:block;padding:13px 0;border-bottom:1px solid var(--line);font-size:1.02rem;color:var(--text)}
  .nav-links a::after{display:none}.nav-links a:hover{transform:none}
  .nav-links .mobile-only{display:block;margin-top:auto;background:var(--gold-shade);color:var(--ink);border:1px solid rgba(90,66,34,.5);border-radius:10px;text-align:center;padding:13px 16px;font-weight:700;box-shadow:inset 0 1px 0 rgba(255,255,255,.5),inset 0 -1px 0 rgba(0,0,0,.18)}
}

/* page header (inner pages) */
.page-head{padding:76px 0 36px;background:linear-gradient(180deg,var(--bg-2),var(--bg));border-bottom:1px solid var(--line)}
.page-head .lede{font-size:1.12rem;color:var(--muted);max-width:60ch;margin-top:18px}
/* The first section has no heading (Michael, 2026-09-12), so its lede is the first thing read on
   the page after the hero and a default paragraph is too quiet to open on. */
#why .lede{font-size:1.15rem;color:var(--muted);max-width:62ch;margin:0}
@media (max-width:720px){.page-head{padding:48px 0 28px}}

/* hero */
.hero{position:relative;padding:48px 0 72px;background:radial-gradient(70% 60% at 80% 0%,var(--hero-glow) 0%,transparent 70%),var(--bg)}
.hero .wrap{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:56px;align-items:center}
@media (max-width:900px){.hero .wrap{grid-template-columns:minmax(0,1fr)}.hero{padding:64px 0 48px}}
/* The hero gilds its payoff - "Casting calls that <accent>book themselves.</accent>" -
   and every section heading now does the same with its own (Michael, 2026-09-17: "apply
   the gold shading to the text that is on the book themselves on the hero page"). One
   rule, one treatment: a gradient clipped to the glyphs in light, flat --gold in dark,
   because a gradient that subtle disappears against the dark ground. */
.hero h1 .accent,
.sec-line .accent{color:var(--gold-dark);background:var(--grad);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.hero .lede{font-size:1.15rem;color:var(--muted);max-width:54ch;margin:22px 0 30px}
.hero .ctas{display:flex;flex-wrap:wrap;gap:12px}

/* app window mock (light) */
.window{background:var(--panel);border:1px solid var(--line-2);border-radius:16px;box-shadow:0 30px 60px -30px rgba(16,24,40,.35),0 1px 2px rgba(16,24,40,.06);overflow:hidden;font-size:.84rem}
.window .chrome{display:flex;align-items:center;gap:8px;padding:10px 14px;border-bottom:1px solid var(--line);background:var(--bg-2)}
.window .chrome i{width:10px;height:10px;border-radius:50%;background:var(--line-2)}
.window .chrome .url{margin-left:8px;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:var(--panel);border:1px solid var(--line);border-radius:7px;padding:4px 10px;color:var(--dim);font-size:.75rem}
.window .body{padding:16px 16px 18px;display:grid;gap:12px}
/* The window cycles through what the product actually does (Michael, 2026-09-13: "can we
   make it so that its like changing every few seconds of parts of the application in this
   same style"). Every screen sits in the SAME grid cell, so the frame is as tall as the
   tallest of them and never resizes between slides - a browser window that changes height
   every four seconds reads as the page breaking, not as a product demo. No height
   animation is needed and none is used. */
.window .body > .shot{grid-area:1/1;display:grid;gap:12px;align-content:start;
  opacity:0;visibility:hidden;transition:opacity .55s ease,visibility 0s linear .55s}
.window .body > .shot.on{opacity:1;visibility:visible;transition:opacity .55s ease}
@media (prefers-reduced-motion:reduce){
  .window .body > .shot{transition:none}
}
.ev{display:flex;justify-content:space-between;align-items:center;gap:10px}
.ev b{font-size:.98rem}
.ev .meta{color:var(--muted);font-size:.8rem;margin-top:2px}
.pill{display:inline-block;padding:3px 9px;border-radius:999px;font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;white-space:nowrap}
/* pills: done is navy with gold lettering (the step numbers and the badge wear the same), pending is soft gold.
   Shaded gold with ink lettering was tried 2026-09-10 and reverted the same day (Michael: "I don't like the change"). */
.pill.ok{background:var(--ink);color:var(--gold-light)}
.pill.amber{background:var(--gold-soft);color:var(--gold-dark)}
.pill.brand{background:var(--gold-soft);color:var(--gold-dark)}
.pill.gray{background:var(--bg-2);color:var(--muted)}
.slot{border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:var(--panel)}
.slot .top{display:flex;justify-content:space-between;gap:10px;align-items:center}
.slot .cast{display:grid;gap:8px;margin-top:10px}
.slot .row{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:9px;background:var(--bg-2)}
.slot .row .av{width:26px;height:26px;border-radius:50%;background:var(--gold-soft);color:var(--gold-dark);display:grid;place-items:center;font-weight:700;font-size:.7rem;flex-shrink:0}
.slot .row .nm{flex:1 1 auto;min-width:0;font-weight:600}
.slot .row .st{color:var(--muted);font-size:.78rem;white-space:nowrap;margin-left:auto}
.sms{border:1px solid var(--line);border-radius:12px;padding:10px 12px;background:var(--panel);color:var(--muted);font-size:.8rem;line-height:1.45}
.sms b{color:var(--text)}
.sms .from{display:block;font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);margin-bottom:4px}


/* strip */

/* The opening section is one picture and no words (Michael, 2026-09-12). A Saturday run by hand
   leaves messages, calls, spreadsheet cells, contracts, invites and payments, and the apps that
   made them sit in the same heap. The apps are their OWN objects at the size an app icon is, not
   glyphs tucked inside the pills, and nothing here is tinted: the shading the pills already carry
   is the only colour in the section.

   THE BAR FOR EVERY LINE IN HERE (2026-09-15, after a sweep of all 192): an owner of an
   entertainment company reads it and knows we have actually run these events. "client called,
   upset" and "did that ever get sorted" are any business on earth and were replaced; a chain
   venue nobody named, a COI the venue wants on the day, a performer who took two gigs, six
   people saying yes to one slot, a wig that never turned up, no W9 on file - those are the
   ones that land. Nineteen lines across the texts, cells, emails and files went that way in
   one pass. When you add a scrap, it has to earn its place by being recognisable, not by
   being plausible. */
/* flex-basis 0, NOT auto. On auto the pile's hypothetical size is its own content, so a heap
   deep enough to overrun made the section grow, which grew the heap, which the top-up then filled
   again: measured at a 900px window, 576 scraps inside a 3773px box. Basis 0 means it takes the
   leftover and nothing else, and overflow:hidden keeps the content out of the calculation. The
   min-height is a floor for a very short window, and it is a fixed number rather than anything
   derived from content, so it cannot re-open the loop. */
.pile{position:relative;flex:1 1 0;min-height:340px;overflow:hidden;display:flex;flex-wrap:wrap;
  align-content:flex-start;align-items:flex-start;gap:6px;padding:4px 2px 0;
  /* align-items MUST be flex-start. A flex container defaults to `normal`, which behaves as
     STRETCH, so every scrap was pulled to the height of the tallest thing in its row - a
     31px pill next to a 112px icon tile rendered as a 119px box. That is what made the heap
     read as boxy and airy at once (measured: t2 pills ranging 47-119px for one font size).
     It got worse the moment the icons got bigger, which is exactly when it was reported. */
  /* THE HEAP IS LAID OUT WIDER THAN IT IS SEEN, and that is the whole reason the right edge
     works (Michael, 2026-09-15: "you get nice full page fade away on the left top and bottom
     but the right doesnt do that"). He was right, and it was never a fade problem - it was
     flex-wrap. A flex line breaks BEFORE the edge, by construction, so every row ended short
     of it: measured across 15 rows at 1177px, the leftover ran 5 to 189px with a median of
     105, against a fade band of 41. Twelve of fifteen rows never reached the fade at all, so
     the right stopped dead in bare background while the left (every row flush at x=2, so the
     fade always eats into the first pill) and the bottom (763px of content in a 600px box)
     both dissolved. No gradient could fix that; there was nothing there to dissolve.

     So the box is pulled out past the wrap on both sides with negative margins, and the mask
     brings the visible band back to exactly the wrap's content box. The right overhang is
     wider than the widest scrap, which makes the bleed a GUARANTEE rather than a coin flip:
     a line's leftover can never exceed the width of the item that failed to fit, so with more
     room past the edge than the widest scrap, every row is cut mid-pill. That is the one
     CONSTRAINT to keep when adding a scrap: 260 is the widest measured scrap (236px, "what
     happened to friday") plus the 6px gap plus slack, so nothing may render wider than 254px. It is not
     greppable - the copy is sized by the font, not by its character count, which runs from
     0.39 to 0.63em per character across this set - so it is MEASURED:
     scripts/pile_bleed_scan.js, pasted into the console, reports any row that falls short.
     The left overhang is small and does a different job - the rows were already flush there,
     which is a ruler-straight line of pill-STARTS softened by a fade; running them out by
     80px means the edge is cutting through pills instead, which is what the bottom does. */
  /* THREE THINGS RAMP WITH THE SCREEN, and all three are one complaint (Michael, 2026-09-15:
     "right now its a mess but on a large monitor its a perfect square ... on a larger monitor
     like mine I want the edges to be messier"). He is on an ultrawide at 100 percent. Measured
     there before this: the heap was a 1432x600 rectangle with a 1004px black gutter down EACH
     side and 484px of dead section under it, covering 24 percent of the screen. Three separate
     causes, so three separate dials, every one of them zero at the width the laptop layout was
     signed off at, so nothing below 1540 moves a pixel.

     --bleed widens what you SEE past the text column. The heading stays in the wrap where a
     line of type belongs; the heap is scenery and should not be held to a 42ch measure. It is
     added to both negative margins, which grows the box, and the mask stops are measured off
     the box edges - so the visible band follows with no change to the gradient at all.

     --mx and --my are the mess. Each scrap carries a unitless --jx / --jy (0..1) and the margins
     are those times these, so the SAME markup is dense on a laptop and ragged on an ultrawide.
     The horizontal one is what breaks the rectangle: rows are laid out from the box's left edge,
     so a random margin on the first scrap of a row indents that WHOLE row, and the left edge
     stops being a ruler. --my was a hard-coded margin-top of 0 to 8px per scrap until now, so
     8px here is the old page exactly.

     Ramps, not breakpoints: a step would make the heap visibly reshuffle at one window width. */
  /* 2.2 rather than 2 leaves a margin that grows with the screen instead of a fixed one, and
     the cap is what a 3440 ultrawide needs: at 520 it still had 484px of black down each
     side, which is the rectangle again. Measured after: 141px. */
  --bleed:clamp(0px,calc((100vw - 1540px) / 2.2),900px);
  /* Cut hard on 2026-09-15 ("this is too big a gap", with a photo of a hole in the heap).
     --mx is a margin on EVERY scrap, so it does two jobs at once and only one of them was
     wanted: it indents the first scrap of a row, which is the ragged edge, and it also widens
     the space between every neighbouring pair, which is the hole. Measured on his ultrawide at
     44: the gap between adjacent scraps ran 6 to 51px with a MEDIAN of 27, against a 6px base.
     At 14 that is 6 to 20, median 13. The row indents come down with it, which is the trade -
     the mess that is left is the vertical jitter and the heap running past the text column. */
  --mx:clamp(0px,calc((100vw - 1400px) / 44),14px);
  --my:clamp(8px,calc(8px + (100vw - 1400px) / 130),14px);
  --over-l:80px;
  /* The overhang has to clear the widest scrap PLUS whatever --mx just added to its left margin,
     or the guarantee below stops being one. */
  --over-r:calc(260px + var(--mx));
  margin-left:calc((var(--over-l) + var(--bleed)) * -1);
  margin-right:calc((var(--over-r) + var(--bleed)) * -1);
  /* Every edge dissolves, not just the bottom (Michael, 2026-09-12, with a photo of a pill cut
     clean in half at the side). Two gradients intersected: one down the page, one across. The
     bottom keeps the long fade; the top is shortest, since the section opens on it and washing
     out the first row reads as a mistake rather than an edge. It matters more since the cursor
     started shoving things out past these edges.
     The side stops are in PX off each edge, not percentages, because they have to land on the
     wrap: fully transparent at the overhang (so nothing paints in the page gutter), opaque
     46px inside it. 46 is what 3.5% of the old box came to, so the fade itself is the length
     it always was - the only thing that changed is that there is now something crossing it. */
  --fade-y:linear-gradient(180deg,transparent 0,#000 3.5%,#000 84%,rgba(0,0,0,.35) 95%,transparent);
  --fade-x:linear-gradient(90deg,transparent 0,transparent var(--over-l),
    #000 calc(var(--over-l) + 46px),#000 calc(100% - var(--over-r) - 46px),
    transparent calc(100% - var(--over-r)));
  -webkit-mask-image:var(--fade-y),var(--fade-x);
  mask-image:var(--fade-y),var(--fade-x);
  -webkit-mask-composite:source-in;
  mask-composite:intersect;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
/* Every scrap used to be one size, two backgrounds and the same padding, so messages,
   emails, contracts and pay statements bled into a single grey texture (Michael,
   2026-09-13: "they all bleed together ... too uniform"). The fix is not more colour, it
   is that SIZE AND WEIGHT CARRY PANIC: a scrap shouting at you is big and dark, dead
   admin is small and faded. Five tiers and two tones do that, and each KIND is a
   different SHAPE so a text is not a spreadsheet cell at a glance.

   No pseudo-element tails or folds in here, however much a bubble wants one: freeze()
   in site.js rewrites `position` on every child to absolute, so an ::after positioned
   against its own pill would re-anchor to the pile the moment the cursor moved. The
   shapes are all border-radius, border-side and colour, which nothing can knock loose. */
.pile > span{display:inline-flex;align-items:center;color:var(--dim);
  white-space:nowrap;border:1px solid var(--line);
  font-size:var(--f,.9rem);padding:.55em .82em;
  /* the scrap's own two random numbers, against the screen's two ramps */
  margin-left:calc(var(--jx,0) * var(--mx));margin-top:calc(var(--jy,0) * var(--my))}
/* The tier no longer carries the SIZE: five classes put 95 scraps on five values with 45
   of them identical, which is the clumping that was obvious on the icon tiles and just as
   real here. --f places each scrap at its own point inside its tier's band (generator).
   Padding is in em so it scales with whatever size the scrap got, from one rule. What the
   tier still carries is WEIGHT, the other half of "this one is shouting". */
.pile > span.t4{font-weight:600}
.pile > span.t5{font-weight:700;letter-spacing:-.01em}
/* tones: what the scrap is doing to you */
.pile > span.loud{color:var(--text);border-color:var(--line-2);box-shadow:var(--shadow)}
.pile > span.faint{opacity:.66;box-shadow:none}
/* The cursor searches the heap rather than hovering it, so nothing in here is a pointer target:
   every mousemove belongs to the pile itself and no object can take a hover off it. */
/* will-change is NOT here. It is set in site.js on the scraps that actually get a physics
   body, which is the visible ones: the heap is laid out far wider and far deeper than the
   box it is seen through, so most of these 152 can never move, and a promoted layer each is
   real compositor memory for nothing. On touch and reduced-motion the engine never runs and
   nothing is promoted at all. */
.pile > *{pointer-events:none}
/* a message: the one corner that is not round is what makes it a bubble */
.bub{background:var(--bg-2);border-radius:18px 18px 18px 6px}
/* an email, from outside, with the thread still on it */
.mail{background:var(--panel);border-radius:9px;border-color:var(--gold-light)}
/* a fragment torn out of a grid, column rule and all */
.cell{background:var(--panel);border-radius:7px;letter-spacing:.01em;
  font-variant-numeric:tabular-nums;border-color:var(--line-2)}
/* a file somebody sent, corner clipped like a page fold */
.doc{background:var(--panel);border-radius:8px 16px 8px 8px;border-color:var(--line-2)}
/* an inquiry off a marketplace: it arrives lit up, which is the problem */
.lead{background:var(--gold-soft);border-radius:999px;border-color:var(--gold-light);color:var(--gold-dark)}
/* an invite somebody typed by hand */
.cal{background:var(--panel);border-radius:10px;border-color:var(--line-2);border-style:dashed}
/* money written down instead of invoiced */
.pile > span.note{background:var(--gold-soft);border-radius:7px;border-style:dashed;
  border-color:var(--gold-light)}
/* THE THING THAT IS ACTUALLY COSTING YOU. The only filled chip in the heap, so it is the one
   kind that reads as a state rather than as paper, and it was renamed from .pay on 2026-09-15:
   "the gold pills that stick out ... are pretty much all focused on invoices or payouts. I want
   to make those focus on ideas that are painpoints". They were eleven out of eleven about money,
   which made the loudest thing on the page a single complaint. They now spread across the four
   that actually hurt - a performer who was never told the details, somebody unpaid, a client or
   venue who has a problem, and a gap where a person should be - with money as ONE of them rather
   than all of them. Keep it that way when adding one: the class is what hurts, not what is owed.
   And SPECIFIC, which the first attempt at this was not: "client called, upset" is any business
   on earth (Michael, 2026-09-15: "this is too generic ... need actual cases that people who work
   in this industry will read and be like oh yeah we struggle with that"). The bar is a chain
   venue nobody named, a call time that never reached the performer, a COI the venue wants on the
   day, a performer who took two gigs, six people saying yes to one slot. They are the things
   this product exists to remove, which is why they belong on this page and not generic ones.
   It was solid ink until 2026-09-13 - "no black icons or pills" - and is now the brand gold,
   which still separates it from every neighbour without a black box landing on a warm page. */
.pile > span.pain{background:var(--gold-light);border-color:var(--gold);color:var(--ink-2);
  border-radius:8px;font-weight:600;font-variant-numeric:tabular-nums}
/* In dark the soft gold fill is too close to the page, so the money chip goes to the full
   gold with ink lettering - "this one is money" has to survive the theme. */
:root[data-theme="dark"] .pile > span.pain{background:var(--gold);border-color:var(--gold);color:var(--ink)}
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
/* On a phone the heap has a third of the width, so the shout end would eat a whole row
   each and the pile would read as a list. Everything comes down a step together, which
   keeps the ORDER intact - panic still reads bigger than admin. Padding is in em, so it
   follows from the one font-size rule. */
/* A phone has a third of the width, so the mess is subtraction there: an indent is a bite out
   of a row that only holds two scraps. Both ramps are already at their floor this narrow; they
   are pinned anyway so a future change to them cannot reach a phone. The height stays a stated
   420 rather than filling, because on a phone the section is a scroll away from the next one and
   a full-viewport heap reads as a wall you have to get past. */
@media (max-width:820px){.pile{flex:0 0 auto;height:420px;min-height:0;gap:8px;
    --over-l:68px;--over-r:224px;--bleed:0px;--mx:0px;--my:8px}
  .pile > span{font-size:calc(var(--f,.9rem) * .86)}}

/* problem / solve */
.solve{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px;margin-top:40px}
@media (max-width:820px){.solve{grid-template-columns:minmax(0,1fr)}}
.solve .col{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:26px 24px;box-shadow:var(--shadow-sm)}
.solve .col.after{border-color:var(--gold-light);background:linear-gradient(180deg,var(--gold-soft),var(--panel) 55%)}
.solve .col h3{font-size:.76rem;letter-spacing:.12em;text-transform:uppercase;color:var(--dim);margin-bottom:14px}
.solve .col.after h3{color:var(--gold-dark)}
.solve ul{margin:0;padding:0;list-style:none;display:grid;gap:12px}
.solve li{display:flex;gap:12px;align-items:flex-start;color:var(--muted);font-size:.97rem}
.solve .col.after li{color:var(--text)}
.solve li svg{flex-shrink:0;margin-top:5px;color:var(--dim)}
.solve .col.after li svg{color:var(--gold-dark)}

/* steps */
.steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:18px;margin-top:40px}
@media (max-width:980px){.steps{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.steps{grid-template-columns:minmax(0,1fr)}}
.step{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:24px 22px 22px;box-shadow:var(--shadow-sm)}
.step .n{width:34px;height:34px;border-radius:10px;background:var(--ink);color:var(--gold-light);display:grid;place-items:center;font-weight:800;margin-bottom:16px}
.step p{color:var(--muted);font-size:.95rem;margin-top:8px}

/* features */
/* Shorter, and sized for three rows: the plan pill came off these cards (Michael,
   2026-09-12), and the padding and the icon block were both set for a card with a fourth
   row under the paragraph.
   RESTORED 2026-09-15 after the three-stage revamp DELETED it: the block that was swapped out
   ran from the grid rule down to `.feat .ic`, and this sat inside that range, so every tile lost
   its panel, its border and its shadow and the section rendered as plain text on the page
   ("needs some background and shading"). The lesson is the boring one: a replacement bounded by
   two landmarks takes everything between them, whether you meant it or not. */
.feat{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:15px 17px 16px;box-shadow:var(--shadow-sm);
  display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:11px;align-items:center;align-content:start;
  transition:box-shadow .15s ease,border-color .15s ease,background-color .15s ease,translate .2s ease}
/* The hover was a deeper shadow and a darker border, quiet enough to read as nothing (Michael,
   2026-09-12: "a hover and very suttle highlight"). It warms and lifts 2px now, the same lift
   the nav links take. The tint is a token because the dark theme needs its own: a near-white
   would light up on navy. */
.feat:hover{box-shadow:var(--shadow);border-color:var(--line-2);background:var(--tile-hover);translate:0 -3px}
/* THE SECTION IS A JOURNEY IN THREE STAGES (his boss's idea, 2026-09-15, then: "revamp the
   whole if needed"). Two earlier attempts were wrong in instructive ways. A flow INSIDE each
   card answered a different question. A chevron between every card in a grid answered the right
   one badly: it is a stray mark in a gap, and an arrow chain BREAKS at the end of every row,
   where your eye runs out of tiles and has to jump back to the left with nothing telling it to.

   Stages fix that structurally rather than cosmetically. Each stage is a COLUMN, so the arrow
   sits between stages and there are only two of them - they cannot break at a row end, because
   a stage is a row end. The nine tiles keep their own order inside their stage, and the numbers
   belong to the stages rather than to the tiles, so nothing has to be renumbered when a tile
   moves.

   Texting spans the whole thing rather than sitting in a stage, because it is not a step: it
   runs across all three. It gets the full width underneath, which is the layout saying so. */
/* --chev is the mark's box; the two gaps are the space it has to sit in. The offsets below
   are computed from them, so "make the arrow bigger" is one number, not three. */
.journey{--chev:18px;--gutter:44px;--stack-gap:34px;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));grid-template-rows:auto auto;
  gap:20px var(--gutter);margin-top:40px}
/* A first cut gave the whole column a ground of its own, which read as a card holding cards.
   Michael, 2026-09-15: "I dont like the tile in a tile thing ... the large back tile needs to
   go. put a small tile between each 1 2 and 3 header." So the card comes OFF the column and
   goes ON the header: one small gold-tinted tile announces the stage, the feature tiles below
   it stand on the page directly, and there is one level of card on the page instead of two.
   The tint is what separates the two kinds - a stage marker is not another feature. */
.stage{display:grid;grid-row:span 2;grid-template-rows:subgrid;gap:12px;position:relative}
.stage-body{display:flex;flex-direction:column;gap:12px}
.stage-head{position:relative;background:var(--gold-soft);border:1px solid var(--line);
  border-radius:var(--radius);padding:12px 16px 13px}
.stage-n{display:block;font-size:.72rem;font-weight:800;letter-spacing:.14em;
  color:var(--gold-dark);opacity:.7;font-variant-numeric:tabular-nums}
.stage-head h4{margin:3px 0 0;font-size:1.02rem;font-weight:800;letter-spacing:-.015em;
  color:var(--text)}
.stage-head p{margin:3px 0 0;color:var(--dim);font-size:.84rem;line-height:1.4}
/* The chevron is a MASKED SVG, not two borders rotated 45deg. Rotating a square puts the
   visual mass off to one side of its box, so a border chevron that is centred in CSS still
   reads as off-centre to the eye - Michael, 2026-09-15: "your arrows just are not hitting ...
   not even centred and just feel wrong". A mask whose path is centred in a square viewBox,
   sized `contain` in a square box, centres the thing you can actually see.

   It hangs off the HEAD rather than the stage, so top:50% is the middle of the pill it points
   out of. That only works because the pills are one height now (the subgrid above); on the
   old ragged heads a fixed offset was the best that could be done, and it was not good.
   Geometry: the box is 18 wide in a 44 gutter, so 13px clear each side. `right` resolves
   against the head's PADDING box, which is inside its 1px border - hence -32, not -31. */
.stage:not(:last-child) > .stage-head::after{content:"";position:absolute;z-index:1;
  top:50%;right:calc(-1px - (var(--gutter) + var(--chev))/2);translate:0 -50%;
  width:var(--chev);height:var(--chev);
  background:var(--gold);opacity:.9;pointer-events:none;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 5L15.5 12 8.5 19'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 5L15.5 12 8.5 19'/%3E%3C/svg%3E") center/contain no-repeat}
/* Texting is the one thing that is not a step - it runs across all three - so it gets the
   full width underneath rather than a place in a stage. As four bullets across two columns
   that read as a fourth feature tile with a hole in it (Michael, 2026-09-16: "I UNDERSTAND
   WHY IT IS SPREAD OUT VIA ALL THREE SECTIONS. THAT SAID IT LOOKS BAD THE WAY IT IS DONE").
   It is a skinny pill now: icon, name, one sentence, on one line. Height is the icon's
   height and nothing else - the padding is equal top and bottom, so the ring around the icon
   is even the whole way round, which is what makes it read as a bar rather than a short card. */
.feat-span{--stack-gap:34px;margin-top:20px;
  grid-template-columns:auto minmax(0,1fr);column-gap:14px;padding:15px 17px}
/* The name and the sentence are INLINE inside one block, not two grid cells. As two cells
   they were two boxes of different line-height being centred independently, so their
   baselines missed by 3px and the sentence sat low - Michael, 2026-09-16: "the sentence is
   not in line with the 'texting service' this is basic shit man". He was right, and box
   centring was the wrong tool: one line of text is what makes two runs share a baseline,
   and the text engine guarantees it at any size or weight. It also wraps properly for free
   - the sentence just runs on to a second line indented past the icon - which is why the
   760px stacking rule that used to be here is gone. */
.feat.feat-span .span-line{line-height:1.45}
.feat.feat-span h3{display:inline}
.feat.feat-span p{display:inline;margin:0 0 0 12px;color:var(--muted);font-size:.95rem}
@media (max-width:900px){
  .journey{grid-template-columns:minmax(0,1fr);gap:var(--stack-gap)}
  /* same arithmetic downwards: centred in the gap under the column */
  .stage:not(:last-child) > .stage-head::after{display:none}
  .stage:not(:last-child)::after{content:"";position:absolute;z-index:1;
    left:50%;translate:-50% 0;bottom:calc(-1 * (var(--stack-gap) + var(--chev))/2);
    width:var(--chev);height:var(--chev);
    background:var(--gold);opacity:.9;pointer-events:none;
    -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 8.5L12 15.5 19 8.5'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 8.5L12 15.5 19 8.5'/%3E%3C/svg%3E") center/contain no-repeat}
  .feat-span{margin-top:var(--stack-gap)}
}
.feat .ic{width:30px;height:30px;border-radius:9px;background:var(--gold-soft);display:grid;place-items:center;color:var(--gold-dark)}
.feat .ic svg{width:18px;height:18px}
.feat p{color:var(--muted);font-size:.95rem;margin-top:6px}
/* Bullets rather than a paragraph (Michael, 2026-09-15: "these things could benefit from
   bullets easier to read ... MAX 4 BULLETS PER"). A marker built from a pseudo-element rather
   than list-style, because a real disc cannot be coloured or sized independently of the text
   and lands too low against a 1.45 line-height. Four is the cap and it is a CAP, not a target:
   a card with three good lines beats one with three good lines and a filler. */
.feat-list{grid-column:1/-1;list-style:none;margin:9px 0 0;padding:0}
.feat-list li{position:relative;color:var(--muted);font-size:.92rem;line-height:1.45;
  padding-left:18px;margin-top:7px}
.feat-list li:first-child{margin-top:0}
.feat-list li::before{content:"";position:absolute;left:2px;top:.58em;width:5px;height:5px;
  border-radius:50%;background:var(--gold);opacity:.85}

/* The Solution: one row per feature (2026-10-05, Michael, on the first two: "maybe have this type of
   design for each amazing feature we have. because it explains it more detail and also gives a
   great visual"), in chapters, each row its copy on one side and the real app on the other, the
   sides swapping row to row, one column with the copy first on a phone. Document Studio is not
   called Documents (Michael: beside "Contracts & bookings" it read as the same thing twice, and as
   storage, "a place for me to store documents ... that's just basic", for a document generator). */
/* The pictures are the real app (2026-10-05, Michael: "truth in what we market ... the images used
   are generic not true to how the app actually looks once you are in it"): Talent Booker's own pages,
   run against a seeded demo company (Acme Talent) and photographed in both themes. The theme the
   visitor is not using is display:none, and a lazy image that is not displayed is never fetched. Today only the hero shows them; .window.real is the hero's frame (the admin pages load this
   sheet too, so nothing here is bare). */
img.th-l,img.th-d{display:block;width:100%;height:auto}
img.th-d{display:none}
:root[data-theme="dark"] img.th-l{display:none}
:root[data-theme="dark"] img.th-d{display:block}
.window.real .body{padding:0;gap:0}
.window.real .body > .shot{display:block}
/* The product section is the three-column journey again (2026-10-06); this line sits under its
   heading. The pictures live in the hero. */
.journey-lede{margin:-6px 0 26px;text-align:center;color:var(--muted);font-size:1.02rem}
.spans .feat-span{margin-top:20px}
/* split */
.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:48px;align-items:center}
@media (max-width:900px){.split{grid-template-columns:minmax(0,1fr);gap:28px}}
.split .lede{color:var(--muted);font-size:1.05rem;margin-top:16px}
.checks{margin:22px 0 0;padding:0;list-style:none;display:grid;gap:12px}
.checks li{display:flex;gap:12px;align-items:flex-start;color:var(--text);font-size:.98rem}
.checks li svg{flex-shrink:0;margin-top:4px;color:var(--gold-dark)}

/* Chapter strip (2026-09-10): the parts of a multi-part page as a quiet tab row, the current part underlined in gold.
   It was pills first, which fought the monthly / yearly switch on Plans (Michael: "this is messy"). */
/* The tabs behave like the bar's links, which every visitor has already learned are clickable: the gold underline
   draws in from the left on hover and the label lifts a touch; the current part keeps its underline (Michael,
   2026-09-10: "not perfectly clear it's a button to press"). */
.chapters{display:flex;flex-wrap:wrap;gap:0 26px;margin-top:22px;border-bottom:1px solid var(--line)}
.chapters a,.chapters button{position:relative;display:inline-block;padding:8px 0 12px;margin-bottom:-1px;border:0;background:none;font:inherit;font-size:.9rem;font-weight:600;color:var(--muted);cursor:pointer;transition:color .15s ease,transform .25s ease}
.chapters a::after,.chapters button::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;border-radius:2px;background:var(--grad);transform:scaleX(0);transform-origin:left;transition:transform .25s ease}
.chapters a:hover,.chapters a[aria-current],.chapters button:hover,.chapters button[aria-selected="true"]{color:var(--text)}
.chapters a:hover::after,.chapters a[aria-current]::after,.chapters a:focus-visible::after,.chapters button:hover::after,.chapters button[aria-selected="true"]::after,.chapters button:focus-visible::after{transform:scaleX(1)}
@media (hover:hover){.chapters a:hover,.chapters button:hover{transform:translateY(-2px)}}
.chapters a:focus,.chapters button:focus{outline:none}
.chapters.top{margin:0}
/* The strips are tabs (2026-09-10): the panel under the strip crossfades to the next and the box
   glides to its height, so nothing above the strip moves and nothing below it moves except to
   make room. The leaving panel is lifted out of flow for the crossfade. */
.tabs{position:relative;margin-top:28px}
#plans .tabs{margin-top:0}
.tabs.moving{overflow:hidden;transition:height .35s cubic-bezier(.2,.7,.2,1)}
/* The box turns on overflow:hidden while it animates its height, and that makes it a block
   formatting context, which stops a child's top margin collapsing out through its edge. The
   content therefore dropped by that margin the moment a switch started and snapped back when
   it ended (Michael, 2026-09-12: "this slight drop down and then the tiles snap in place").
   The panel is its own formatting context now, so the layout is identical whether or not the
   box is moving. flow-root, not overflow:hidden: the panel must not clip the card shadows. */
.panel{transition:opacity .28s ease;display:flow-root}
.panel[hidden]{display:none}
.panel.entering{opacity:0}
.panel.leaving{position:absolute;left:0;right:0;top:0;opacity:0;pointer-events:none}
/* A contained margin would STACK with the tab strip's own, where it used to collapse into it,
   so the three first children give theirs up and the strip keeps owning that space. This is
   what the Onboarding card already did; the other two join it, and all three tabs start at the
   same height. */
#plans .panel > .tiers,
#plans .panel > .addons,
#plans .panel > .onboard{margin-top:0}
/* the monthly-or-yearly switch belongs to the plans themselves, so it goes with them */
.plans-top .billing{transition:opacity .25s ease,visibility 0s linear 0s}
#plans:not([data-tab="0"]) .billing{opacity:0;visibility:hidden;pointer-events:none;transition:opacity .25s ease,visibility 0s linear .25s}
/* Plans: the strip and the switch share one row, strip left, switch right. */
.plans-top{display:flex;justify-content:space-between;align-items:flex-end;gap:18px;flex-wrap:wrap;margin-bottom:12px}
.plans-top .billing{margin:0}
/* Beside the cards the switch takes the third column exactly, so its box lines up with the card under it
   (Michael, 2026-09-10); the saving drops to its own line as it does on the phone. */
@media (min-width:901px){
  /* one line, the old height: the monthly half keeps its natural width and the yearly half takes the rest */
  .plans-top .billing{display:inline-flex;width:calc((100% - 32px) / 3)}
  .plans-top .billing button{flex:0 0 auto;white-space:nowrap}
  .plans-top .billing button[data-billing="yearly"]{flex:1 1 auto}
}
.onboard{margin-top:0}

/* plans */
.plans{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:18px;margin-top:40px;align-items:stretch}
/* the launch pricing draft (2026-09-09): three roster tiers, the middle one lit */
/* Plan cards (2026-09-09): feature tiers, in the card shape Michael pointed at. Each card carries its own
   list; the monthly / yearly switch above them flips one class, and both prices are in the markup. */
/* The switch: one navy thumb slides between the two halves and resizes to fit (Michael, 2026-09-10: the swap was
   abrupt); site.js places it from the active button's offsets. No focus ring on the buttons. */
.billing{position:relative;display:inline-flex;margin-top:0;padding:4px;border:1px solid var(--line-2);border-radius:999px;background:var(--bg-2);gap:2px}
.billing .thumb{position:absolute;top:4px;bottom:4px;left:4px;width:0;border-radius:999px;background:var(--ink);transition:left .3s cubic-bezier(.22,.61,.36,1),width .3s cubic-bezier(.22,.61,.36,1)}
.billing button{position:relative;z-index:1;font:inherit;font-size:.9rem;font-weight:600;color:var(--muted);background:transparent;border:0;border-radius:999px;padding:8px 16px;cursor:pointer;transition:color .25s ease}
.billing button span{font-weight:600;color:var(--gold-dark);margin-left:8px;font-size:.82rem;transition:color .25s ease}
.billing button.on{color:#fff}
.billing button.on span{color:var(--gold-light)}
.billing button:focus,.billing button:focus-visible{outline:none}
.tiers{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px;margin-top:12px}
@media (max-width:1180px){.tiers{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:900px){.tiers{grid-template-columns:minmax(0,1fr)}}
.tier{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:26px 26px 26px;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;gap:9px}
.tier.featured{border-color:var(--gold-light);background:linear-gradient(180deg,var(--gold-soft),var(--panel) 45%);box-shadow:var(--shadow)}
/* The ceiling needs an answer ON the card that states it, not under the grid. It lived only in
   the FAQ, four sections below where it is read (Michael, 2026-09-14: "we dont want larger
   entertainment agencies to hop on and be like oh this isnt for big companies"), and a band
   under the three cards answered it but "expands the page" - this section already ends past the
   fold, and the band added 105px to it. The tier-sub is the one place that costs NOTHING: the
   line is already there, already the divider under the price, and on Complete it is the exact
   line that says 1,000. So the limit and the way past it are the same sentence and cannot be
   read apart. Inline on one line where the card is wide enough, its own line where it is not. */
.tier-sub a{color:var(--gold-dark);text-decoration:underline;text-decoration-color:var(--gold-light);
  text-underline-offset:3px;text-decoration-thickness:1px;margin-left:2px;font-weight:600;
  /* An inline box ignores vertical padding when the line box is measured, so this buys a real
     thumb target on a phone (18px of text becomes ~38px of tappable) and costs zero layout. */
  padding:10px 3px}
.tier-sub a:hover{text-decoration-color:var(--gold-dark)}
/* sales tax (2026-10-20): one line under the plans; the Order Form says prices exclude taxes, so does the page */
.plans-tax{margin:16px 0 0;text-align:center;font-size:.88rem;color:var(--dim)}
.tier-head{display:flex;justify-content:space-between;align-items:center;gap:10px}
.tier-head .badge{display:inline-block;padding:3px 9px;border-radius:999px;font-size:.68rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;background:var(--ink);color:var(--gold-light);white-space:nowrap}
.tier-for{color:var(--muted);font-size:.95rem;margin:0}
/* side by side, the one-line and two-line taglines would push the rows out of line; two lines are reserved */
@media (min-width:901px){.tier-for{min-height:3.2em}}
.tier .price{font-size:1.9rem;font-weight:800;letter-spacing:-.03em;line-height:1;margin-top:6px;color:var(--text)}
.tier .price .per{font-size:1rem;font-weight:600;color:var(--muted);margin-left:6px;letter-spacing:0}
.tier-note{font-size:.85rem;color:var(--dim)}
/* One price per card. On the switch the figure slides out and the new one slides in, up for yearly and
   down for monthly, while the box widens or narrows to fit so the unit glides across; the unit fades.
   The count-up went (Michael, 2026-09-10: "a smooth transition, not a rapid fire count up"). The clip
   is the box's own width with a little room on every side (the last glyph's ink may sit a hair past the box
   under the negative tracking), so the leaving figure wipes at the edges and nothing is clipped at rest. */
.tier .price .amt{position:relative;display:inline-block;vertical-align:baseline;clip-path:inset(-.15em -.06em -.15em -.04em);transition:width .3s cubic-bezier(.2,.7,.2,1)}
.tier .price .amt .fig{display:inline-block}
.tier .price .amt .out{position:absolute;left:0;top:0;white-space:nowrap;pointer-events:none}
.tier .price .amt.up .fig{animation:fig-up-in .3s cubic-bezier(.2,.7,.2,1) both}
.tier .price .amt.up .out{animation:fig-up-out .3s cubic-bezier(.2,.7,.2,1) both}
.tier .price .amt.down .fig{animation:fig-down-in .3s cubic-bezier(.2,.7,.2,1) both}
.tier .price .amt.down .out{animation:fig-down-out .3s cubic-bezier(.2,.7,.2,1) both}
@keyframes fig-up-in{from{opacity:0;transform:translateY(.45em)}to{opacity:1;transform:none}}
@keyframes fig-up-out{from{opacity:1;transform:none}to{opacity:0;transform:translateY(-.45em)}}
@keyframes fig-down-in{from{opacity:0;transform:translateY(-.45em)}to{opacity:1;transform:none}}
@keyframes fig-down-out{from{opacity:1;transform:none}to{opacity:0;transform:translateY(.45em)}}
.tier .price .per{transition:opacity .2s ease}
.tier .price .per.fade{opacity:0}
.tier .tier-sub{font-weight:600;font-size:.93rem;color:var(--gold-dark);padding-bottom:12px;margin-bottom:6px;border-bottom:1px solid var(--line)}
.tier-h{font-size:.76rem;letter-spacing:.1em;text-transform:uppercase;font-weight:700;color:var(--dim);margin-top:6px}
.ticks{list-style:none;margin:0;padding:0;display:grid;gap:9px;color:var(--muted);font-size:.92rem;line-height:1.45;flex:1;align-content:start}
.ticks li{display:flex;gap:9px;align-items:flex-start}
/* THREE row types in a plan, and they carried three different marks. Getting this
   wrong once is what makes it worth writing down:

     plain  - what the tier includes.      CHECKMARK -> now a bullet
     .add   - what it adds OVER the tier
              below it.                    PLUS, and the plus STAYS
     .adds  - the "GROWTH ADDS" heading.   no mark, and still none

   Michael, 2026-09-17: bullets are cleaner for the plain rows ("I THINK IT WILL LOOK
   CLEANER"), but the first pass stripped the plus as well - "NO THE + NEEDS TO STAY
   FOR THE ADDS ONES THAT LOOKED GOOD". He is right and the distinction is semantic,
   not decorative: a plus is the only thing on the card saying this line is EXTRA on
   top of the cheaper plan. A bullet there would read as just another feature and the
   tiers would stop laddering.

   The bullet is the dot .feat-list already uses - 5px of --gold at .85 - so the two
   bulleted lists on the page are the same mark. It is a flex child like the svg it
   replaced, so the row keeps its gap and align-items:flex-start, and .58em is the
   offset .feat-list had already proved against this line-height. */
.ticks li svg{flex-shrink:0;margin-top:3px;color:var(--gold-dark)}
/* The plus and the dot are different SIZES, so starting both at x=0 does not line them
   up - measured, the dot's centre sat at 2.5 and the plus's at 8, and the text after it
   at 25 against the dot rows' 14 (Michael, 2026-09-17: "CAN WE GET THE + LINED UP WITH
   THE DOTS?"). The -5.5 either side pulls the 16px glyph back to the 5px ADVANCE the
   dot occupies: centre -5.5+8 = 2.5, text 5+9 = 14. Both now match the dot rows exactly.
   The glyph overhangs the li by 5.5px, which is why this is safe: nothing between here
   and .tier clips, and .tier carries 26px of padding for it to sit in.
   Vertically they already agreed - dot .58em+2.5 = 11.04, plus 3+8 = 11. */
.ticks li.add svg{margin-left:-5.5px;margin-right:-5.5px}
.ticks li:not(.adds):not(.add)::before{content:"";flex:0 0 auto;width:5px;height:5px;
  border-radius:50%;background:var(--gold);opacity:.85;margin-top:.58em}
/* Parallel cards (2026-09-10): the same headings on every card; the shared lines tick, what a tier ADDS
   sits under its own label with a gold plus in bold, so a row reads across the three. */
.ticks li.add{color:var(--text);font-weight:600}
.ticks li.adds{display:block;margin-top:6px;padding-top:10px;border-top:1px solid var(--line);font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;color:var(--gold-dark);font-weight:700}
.tier-addons{color:var(--muted);font-size:.85rem;margin:3px 0 0;padding-top:7px;border-top:1px solid var(--line);line-height:1.4}
.tier-addons b{color:var(--text);margin-right:6px}
.tier .tier-h + .tier-sub{padding-bottom:0;border-bottom:none}
.tier .tier-h{margin-top:2px}
.tier .btn{margin-top:14px;padding:11px 16px}
.onboard{margin-top:22px;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:28px 26px;box-shadow:var(--shadow-sm)}
.onboard .top{display:flex;justify-content:space-between;align-items:flex-start;gap:10px}
.onboard .price-tag{font-weight:800;font-size:1.15rem;color:var(--text);white-space:nowrap;letter-spacing:-.02em}
.onboard .price-tag small{font-size:.8rem;font-weight:600;color:var(--muted);margin-left:2px}
.onboard p{color:var(--muted);font-size:.95rem;margin-top:8px}
.onboard ul{margin:12px 0 0;padding:0;list-style:none;display:grid;gap:9px;color:var(--muted);font-size:.95rem}
.onboard ul b{color:var(--text)}
.onboard li{padding-left:18px;position:relative}
.onboard li::before{content:"";position:absolute;left:0;top:10px;width:6px;height:6px;border-radius:50%;background:var(--gold)}
.onboard .foot{margin-top:14px;padding-top:12px;font-size:.85rem;color:var(--dim);border-top:1px solid var(--line)}
.addon .price-tag{font-weight:800;font-size:1.15rem;color:var(--text);white-space:nowrap;letter-spacing:-.02em}
.addon .price-tag small{font-size:.8rem;font-weight:600;color:var(--muted);margin-left:2px}
@media (max-width:900px){.plans{grid-template-columns:minmax(0,1fr)}}
.plan{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:28px 26px;box-shadow:var(--shadow-sm)}
.plan.base{border-color:var(--gold-light);background:linear-gradient(180deg,var(--gold-soft),var(--panel) 45%)}
.plan .price{font-size:1.4rem;font-weight:800;margin:10px 0 4px;letter-spacing:-.02em}
.plan ul{margin:18px 0 0;padding:0;list-style:none;display:grid;gap:9px;color:var(--muted);font-size:.95rem}
.plan ul b{color:var(--text)}
.plan li{padding-left:24px;position:relative}
.plan li::before{content:"";position:absolute;left:0;top:6px;width:14px;height:14px;border-radius:50%;background:var(--gold-soft);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237A6138' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");background-size:9px;background-repeat:no-repeat;background-position:center}
.addons{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;margin-top:36px}
@media (max-width:980px){.addons{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.addons{grid-template-columns:minmax(0,1fr)}}
.addon{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:24px 22px;display:flex;flex-direction:column;gap:10px;box-shadow:var(--shadow-sm)}
.addon .top{display:flex;justify-content:space-between;align-items:flex-start;gap:10px}
.addon p{color:var(--muted);font-size:.95rem}
.addon ul{margin:6px 0 0;padding:0;list-style:none;color:var(--muted);font-size:.9rem;display:grid;gap:5px}
.addon li{padding-left:18px;position:relative}
.addon li::before{content:"";position:absolute;left:0;top:10px;width:6px;height:6px;border-radius:50%;background:var(--gold)}
.addon .foot{margin-top:auto;padding-top:12px;font-size:.85rem;color:var(--dim);border-top:1px solid var(--line)}
.compare{width:100%;border-collapse:collapse;margin-top:36px;font-size:.95rem;background:var(--panel);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.compare th,.compare td{text-align:left;padding:12px 14px;border-bottom:1px solid var(--line);vertical-align:top}
.compare thead th{background:var(--bg-2);color:var(--dim);font-size:.76rem;letter-spacing:.1em;text-transform:uppercase;font-weight:700}
.compare td:first-child{color:var(--text);font-weight:600}
.compare td{color:var(--muted)}
.compare tr:last-child td{border-bottom:none}
/* the tier matrix (2026-09-09): tiers centred, ticks in gold, the key rows in ink, spanning lines muted */
.compare thead th:not(:first-child){text-align:center}
.compare td:nth-child(2),.compare td:nth-child(3),.compare td:nth-child(4){text-align:center;white-space:nowrap}
.compare tr.k td{color:var(--text);font-weight:700}
.compare tr.k td:first-child{color:var(--muted);font-weight:600}
.compare td.t{color:var(--gold-dark);font-weight:800;font-size:1.05rem}
.compare td.all{text-align:center;white-space:normal}
.compare td.a{white-space:nowrap}
.compare td.a small{font-size:.8rem;color:var(--dim);font-weight:500}
/* Michael, 2026-09-15: "this scroll bar looks fucking awful when the page is short enough to
   need it". It was the platform default - a grey trough with arrow BUTTONS at each end, sitting
   flush under a rounded dark table. Thin, no buttons, no track, a rounded thumb in the theme's
   own warm neutral, and 10px of air between the table's bottom border and the bar.
   Both syntaxes on purpose, and neither is redundant: Chrome 121+ and Firefox read
   scrollbar-width / scrollbar-color and IGNORE the ::-webkit- rules once scrollbar-width is set;
   Safari and older Chrome read only the ::-webkit- ones. Drop either half and one engine is back
   on the default. overscroll-behavior-x stops a trackpad swipe past the last column from turning
   into a browser back-navigation, which on a one-page site means losing your place entirely. */
.table-wrap{overflow-x:auto;border-radius:12px;padding-bottom:10px;
  scrollbar-width:thin;scrollbar-color:var(--scroll-thumb) transparent;overscroll-behavior-x:contain}
.table-wrap::-webkit-scrollbar{height:9px}
.table-wrap::-webkit-scrollbar-track{background:transparent}
.table-wrap::-webkit-scrollbar-button{display:none;width:0;height:0}
.table-wrap::-webkit-scrollbar-thumb{background:var(--scroll-thumb);border-radius:999px}
.table-wrap::-webkit-scrollbar-thumb:hover{background:var(--scroll-thumb-hover)}
/* What it replaces (2026-09-10): the job, the tools used for it today, what EntertainHQ does instead. */
.replaces{width:100%;border-collapse:collapse;margin-top:36px;font-size:.95rem;background:var(--panel);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.replaces th,.replaces td{text-align:left;padding:14px 16px;border-bottom:1px solid var(--line);vertical-align:top}
.replaces thead th{background:var(--bg-2);color:var(--dim);font-size:.76rem;letter-spacing:.1em;text-transform:uppercase;font-weight:700}
.replaces th:nth-child(1),.replaces td:nth-child(1){width:22%}.replaces th:nth-child(2),.replaces td:nth-child(2){width:32%}
.replaces td:first-child{color:var(--text);font-weight:700}
.replaces td:nth-child(2){color:var(--muted)}
.replaces td:nth-child(3){color:var(--text)}
.replaces .yes{display:flex;gap:9px;align-items:flex-start}.replaces .yes svg{flex-shrink:0;margin-top:5px;color:var(--gold-dark)}
.replaces tr:last-child td{border-bottom:none}

/* about */
.people{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px;margin-top:40px}
@media (max-width:820px){.people{grid-template-columns:minmax(0,1fr)}}
.person{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:28px 26px;box-shadow:var(--shadow-sm)}
.person .avatar{width:96px;height:96px;border-radius:22px;object-fit:cover;object-position:center top;background:var(--gold-soft);color:var(--gold-dark);display:grid;place-items:center;font-weight:800;font-size:1.35rem;margin-bottom:18px;letter-spacing:.02em}
.person .role{color:var(--gold-dark);font-weight:600;font-size:.9rem;margin-top:4px}
.person p{color:var(--muted);margin-top:12px;font-size:.97rem}
.story{max-width:70ch}
/* About in one view (2026-09-10, second cut after "shoved together and non premium"): the story as three numbered cards
   in the How-it-works language, the people as cards with the portrait beside the text and room around it. */
#about .lede{margin-top:16px;font-size:1.08rem;color:var(--muted);max-width:66ch}
.steps.three{grid-template-columns:repeat(3,minmax(0,1fr));margin-top:28px}
@media (max-width:980px){.steps.three{grid-template-columns:minmax(0,1fr)}}
.people.compact{margin-top:22px}
.people.compact .person{display:flex;gap:20px;align-items:flex-start;padding:26px}
.people.compact .avatar{width:88px;height:88px;border-radius:22px;margin:0;flex-shrink:0;font-size:1.2rem}
.people.compact h3{font-size:1.2rem}.people.compact .role{margin-top:3px;font-size:.9rem}.people.compact p{font-size:.95rem;line-height:1.6;margin-top:10px}
.story p{color:var(--muted);font-size:1.05rem;margin-top:16px}
.story p b{color:var(--text)}
.todo{display:inline-block;background:var(--gold-soft);color:var(--gold-dark);border:1px dashed var(--gold-light);border-radius:8px;padding:2px 8px;font-size:.78rem;font-weight:600}

/* forms */
.form{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:28px 26px;display:grid;gap:18px;box-shadow:var(--shadow-sm)}
.grid-2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px}
@media (max-width:640px){.grid-2{grid-template-columns:minmax(0,1fr)}}
label{display:grid;gap:7px;font-size:.88rem;font-weight:600;color:var(--text)}
label span b{color:var(--gold-dark)}
/* A question over a group of chips is a fieldset (a label may not hold labels); it reads like the other labels. */
.field{display:grid;gap:7px;font-size:.88rem;font-weight:600;color:var(--text);border:0;padding:0;margin:0;min-width:0}
.field legend{padding:0;margin:0 0 7px}.field legend b{color:var(--gold-dark)}
input,select,textarea{width:100%;background:var(--panel);border:1px solid var(--line-2);border-radius:10px;color:var(--text);padding:12px 14px;font:inherit;font-size:.95rem;outline:none;transition:border-color .15s ease,box-shadow .15s ease}
input::placeholder,textarea::placeholder{color:#8e919b}
input:focus,select:focus,textarea:focus{border-color:var(--gold);box-shadow:0 0 0 3px rgba(200,165,106,.25)}
textarea{min-height:130px;resize:vertical}
select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%234b4f5a' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:40px}
/* Custom dropdowns (2026-09-09): the native select is hidden and keeps the value; this is what shows. The
   panel matches the trigger's width exactly, clips sideways, and scrolls past sixteen rows. */
.dd{position:relative}
.dd select{position:absolute;opacity:0;pointer-events:none;width:1px;height:1px}
.dd-btn{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;background:var(--panel);border:1px solid var(--line-2);border-radius:10px;color:var(--text);padding:12px 14px;font:inherit;font-size:.95rem;cursor:pointer;text-align:left;transition:border-color .15s ease,box-shadow .15s ease}
.dd-btn.empty{color:var(--dim)}
.dd.open .dd-btn{border-color:var(--gold);box-shadow:0 0 0 3px rgba(200,165,106,.25);outline:none}
.dd-btn svg{flex-shrink:0;transition:transform .15s ease;color:var(--muted)}
.dd.open .dd-btn svg{transform:rotate(180deg)}
.dd-panel{position:absolute;z-index:30;top:calc(100% + 6px);left:0;width:100%;background:var(--panel);border:1px solid var(--line-2);border-radius:10px;box-shadow:var(--shadow);padding:5px;max-height:18rem;overflow-y:auto;overflow-x:hidden;display:none}
.dd.open .dd-panel{display:block}
.dd-opt{display:block;width:100%;padding:9px 11px;border:0;border-radius:8px;background:transparent;color:var(--text);font:inherit;font-size:.95rem;text-align:left;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dd-opt:hover,.dd-opt.active{background:var(--gold-soft);color:var(--gold-dark)}
.dd-opt.selected{font-weight:700;color:var(--gold-dark)}
.choices{display:flex;flex-wrap:wrap;gap:8px}
/* "Other" opens a box for the product's actual name. It shares name="tools" with the chips,
   and the function joins form.getAll("tools") with commas, so what they type arrives in the
   same list as what they ticked - no new field, nothing to add at the other end. */
.other-tool{margin-top:10px}
.other-tool[hidden]{display:none}
.choices input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}
.choices span{display:inline-block;padding:8px 12px;border-radius:999px;border:1px solid var(--line-2);font-size:.88rem;color:var(--muted);cursor:pointer;user-select:none;background:var(--panel)}
.choices input:checked + span{background:var(--gold-soft);border-color:var(--gold-light);color:var(--gold-dark)}
.choices input:focus-visible + span{box-shadow:0 0 0 3px rgba(200,165,106,.35)}
.hp{position:absolute;left:-9999px;top:-9999px;opacity:0}
/* Send sits on the RIGHT, where the eye finishes the form, and carries the same shaded
   gold as Book a demo in the hero - the two are the same ask, so they should look it. The
   note reads first and the button is what you land on. It was an inline style; it needs a
   class now because the phone layout below has something to say about it. */
.form-send{display:flex;gap:12px;flex-wrap:wrap;align-items:center;justify-content:space-between}
.form-note{font-size:.85rem;color:var(--dim)}
.alert{border-radius:10px;padding:12px 14px;font-size:.92rem;display:none}
.alert.ok{display:block;background:var(--ok-soft);border:1px solid #a7f3d0;color:var(--ok)}
.alert.err{display:block;background:var(--red-soft);border:1px solid #fecaca;color:var(--red)}
.contact-grid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);gap:28px;align-items:start;margin-top:0}
@media (max-width:900px){.contact-grid{grid-template-columns:minmax(0,1fr)}}
.aside{background:var(--bg-2);border:1px solid var(--line);border-radius:var(--radius);padding:24px 22px;display:grid;gap:18px}
.aside h3{font-size:.95rem}
.aside p{color:var(--muted);font-size:.93rem;margin-top:4px}
.aside a{color:var(--gold-dark);font-weight:600;display:inline-block;padding:4px 0}

/* faq */
/* Questions: two independent stacks, so an open answer moves only the questions below it in its own column and the
   other column never reacts (Michael, 2026-09-10: a row that grew an empty neighbour was "horrible design"). The
   answer glides (site.js); the plus turns to a cross. */
.faq{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;margin-top:36px;align-items:start}
.faq-col{display:grid;gap:16px;align-content:start;min-width:0}
/* Grouped questions (2026-09-10): a small heading per group, the grid under it. */
.faq-group{margin-top:34px}
/* The heading above these is gone (Michael, 2026-09-12), so the first group leads the section
   and the 34px that separates a group from the one above it is separating it from nothing.
   First group only: on .faq-group it would close the gap between every group on the page. */
#faq .wrap > .faq-group:first-child{margin-top:0}.faq-group h3{font-size:.76rem;letter-spacing:.12em;text-transform:uppercase;color:var(--gold-dark);font-weight:700}
.faq-group .faq{margin-top:14px}
@media (max-width:820px){.faq{grid-template-columns:minmax(0,1fr)}}
/* Two continuous columns, each topic whole inside one (Michael, 2026-10-01: "if you expand a question it
   pushed down both columns make it where it only pushes down its column"). Each topic used to be its own
   full-width row split in two, so a topic could only start below the TALLER column of the one above:
   opening a question moved its own column AND every topic under it, both columns, 113px. Now the page is
   two stacks of topics (split by question count, 17 and 17, order kept), and a topic's questions are one
   column, so an answer can only push down what is under it in its own stack. The .faq wrapper stays because
   site.js finds the accordion's questions through `.faq details`. On phones the stacks run one after the
   other, so the topics still read 1 to 8; the second stack keeps its first topic's normal top margin there. */
.faq-cols{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:16px;align-items:start}
.faq-cols .faq{grid-template-columns:minmax(0,1fr)}
.faq-stack{min-width:0}
.faq-stack:first-child > .faq-group:first-child{margin-top:0}
@media (min-width:821px){.faq-stack > .faq-group:first-child{margin-top:0}}
@media (max-width:820px){.faq-cols{grid-template-columns:minmax(0,1fr)}}
details{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:4px 20px;box-shadow:var(--shadow-sm)}
summary{cursor:pointer;font-weight:700;padding:14px 0;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:12px}
summary::-webkit-details-marker{display:none}
/* The plus is half again the text size; it turns to a cross as the answer opens and snaps straight back when it
   closes (Michael, 2026-09-10: the way back "takes a bit too long"). The closing class turns it at the click,
   not when the height animation has finished. */
summary::after{content:"+";color:var(--gold-dark);font-weight:700;font-size:1.5em;display:inline-block;line-height:1;transition:transform .12s ease}
details[open] summary::after{transform:rotate(45deg);transition:transform .2s ease}
details.closing summary::after{transform:none;transition:transform .12s ease}
.ans{overflow:hidden}
details p{color:var(--muted);padding:0 0 16px;font-size:.95rem}
details{transition:border-color .15s ease}details:hover{border-color:var(--line-2)}
/* No box on a question, on click or on keyboard (Michael, 2026-09-10: "another odd highlight thing"); keyboard focus shows on the plus. */
summary:focus,summary:focus-visible{outline:none}summary:focus-visible::after{color:var(--text)}

/* cta */
.cta{background:var(--dark);color:#fff;border-radius:20px;padding:52px 32px;text-align:center}
.cta h2{color:#fff}
.cta .eyebrow{color:var(--gold-light)}
.cta p{color:#d5d0c6;max-width:60ch;margin:14px auto 26px;font-size:1.05rem}
.cta .ctas{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}
.cta .btn-primary{background:var(--gold);color:var(--ink)}
.cta .btn-primary:hover{background:var(--gold-light)}
.cta .btn-ghost{background:transparent;color:#fff;border-color:rgba(255,255,255,.35);box-shadow:none}
.cta .btn-ghost:hover{background:rgba(255,255,255,.08)}

/* 404.html: the mark, one line, two buttons, centred. */
.lost{min-height:calc(100vh - 60px);display:grid;place-items:center;text-align:center;padding:48px 0}
.lost .wrap{max-width:640px}.lost-mark{width:96px;height:96px;margin:0 auto 22px;object-fit:contain;display:block}
.lost .lede{color:var(--muted);font-size:1.1rem;margin:16px auto 28px;max-width:40ch}.lost .ctas{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}
footer{border-top:1px solid var(--line);padding:34px 0 44px;color:var(--dim);font-size:.88rem;background:var(--panel)}
footer .wrap{display:flex;flex-wrap:wrap;justify-content:space-between;gap:14px;align-items:center}
/* The footer carries the copyright line and nothing else: no nav, no address
   (Michael, 2026-09-14: "no nav at all" ... "remove the email too"). Every rule that
   styled a link down here went with them rather than being left pointing at nothing. */
/* These cards are .reveal, and the reveal outranks a component rule twice over. It ends on
   `.js-ready .reveal.in{transform:none}`, three classes against the two in .feat:hover, which
   is why a lift written as a transform never appeared (Michael, 2026-09-12: "highlight worked
   but no hover happened"). And it sets `transition:opacity .6s,transform .6s` at two classes
   against the one in .feat, which dropped the transition too, so the tint was snapping in
   rather than fading. The lift uses translate, which the reveal never touches and which
   composes with its transform; the transition is restated here at a weight that wins. */
.js-ready .feat.reveal{transition:opacity .6s ease var(--rise-delay,0s),transform .6s ease var(--rise-delay,0s),
  box-shadow .15s ease,border-color .15s ease,background-color .15s ease,translate .2s ease}
@media (prefers-reduced-motion:reduce){.btn,.feat{transition:none}}

/* ---- phones (2026-09-09 mobile pass): measured at 375px; nothing below touches desktop ---- */
/* No pinch-zoom and no double-tap zoom on phones (Michael, 2026-09-09, as in the app): pan-x pan-y
   keeps every scroll and excludes the zoom gestures; the viewport meta covers Android; iOS Safari
   ignores that meta, so site.js closes pinch with the gesture events. */
html{-webkit-text-size-adjust:100%;touch-action:pan-x pan-y}
/* Nothing may make the page wider than the screen (Michael, 2026-10-01: "on the mobile marketing side you
   can scroll side to side that needs to be disabled asap"). The cause was the Why pile: on phones it
   overhangs the screen on purpose (--over-l / --over-r, 68px and 224px) so the cards spill off both edges,
   and only body{overflow-x:clip} was hiding the excess - which iOS Safari does not honour for panning, so
   the page was 579px wide on a 375px phone and dragged sideways. The section that owns the overhang now
   clips it, so the cards still bleed to the screen edge and nothing passes it; `hidden` first is the
   fallback for browsers without `clip` (the section has no vertical overflow, so it never scrolls). The
   html rule is the backstop for whatever overhangs next; `clip` makes no scroll container, so the sticky
   table headers are unaffected. */
#why{overflow-x:hidden;overflow-x:clip}
.ts:empty{display:none}.ts{margin:2px 0 12px}
html{overflow-x:clip}
h1,h2{text-wrap:balance}
p,li,legend{text-wrap:pretty}
.price,.price-tag,.compare td,.tier-sub,.tier-note{font-variant-numeric:tabular-nums}
code{overflow-wrap:anywhere}
@media (max-width:640px){
  .wrap{padding:0 20px}
  section{padding:20px 0 52px}
  .eyebrow{font-size:.7rem;letter-spacing:.1em;line-height:1.35}
  .hero{padding:40px 0 44px}
  .hero .wrap{gap:36px}
  .hero .lede{font-size:1.02rem;margin:16px 0 22px}
  /* Side by side, not two full-width stacked pills (Michael, 2026-09-14). Equal halves rather
     than intrinsic widths, or "Book a demo" and "See plans" come out different sizes and read as
     a primary and an afterthought. flex:1 1 0 with min-width:0 is the pair that does it: a flex
     item's automatic minimum size is its CONTENT, and .btn goes white-space:normal at this
     breakpoint, so without min-width:0 the longer label sets the width and the split is uneven. */
  .hero .ctas{flex-direction:row;flex-wrap:nowrap;gap:10px}
  .hero .ctas .btn{flex:1 1 0;min-width:0;width:auto;padding-left:12px;padding-right:12px}
  .cta .ctas .btn{width:100%}
  .hero .note{flex-direction:column;gap:10px;margin-top:22px}
  .btn{padding:13px 20px;font-size:1rem;white-space:normal;text-align:center}
  .btn-wide{width:100%}
  .window{font-size:.9rem;border-radius:14px}
  .window .body{padding:14px 12px;gap:10px}
  .slot{padding:11px 12px}
  .born{padding:18px 0}.born .wrap{font-size:.9rem}
  .page-head{padding:36px 0 24px}.page-head .lede{font-size:1.02rem;margin-top:14px}
  .solve{margin-top:28px;gap:14px}.solve .col{padding:20px 18px}
  .steps,.features,.addons,.plans,.people,.faq{margin-top:28px;gap:14px}
  .faq-group{margin-top:26px}.faq-group .faq{margin-top:12px}.faq-col{gap:14px}
  .tiers{margin-top:22px;gap:14px}.tier{padding:22px 18px}
  /* the switch spans the wrap, two equal halves, the saving on its own line: at 375px the pill wrapped its own labels */
  .billing{display:flex;width:100%;margin-top:20px}
  .plans-top{flex-direction:column;align-items:stretch;gap:12px}.plans-top .billing{margin-top:4px}
  .billing button{flex:1;padding:8px 10px;font-size:.88rem;white-space:nowrap}
  .billing button span{display:block;margin:2px 0 0;font-size:.72rem}
  /* Stacked, a hidden-by-visibility switch is 54px of blank band between the tab strip and the
     panel, on the two tabs where it does not apply (Michael, 2026-09-14: "on the add-ons. too
     much padding between the sub nav bar and the top of the add on block way too much"). Side by
     side on desktop it costs no vertical space, so this is a phone-only collapse; visibility
     alone is kept there because it stops the row jumping as you switch. */
  #plans:not([data-tab="0"]) .billing{height:0;min-height:0;margin:0;padding:0;border-width:0;overflow:hidden}
  .step,.feat,.addon,.plan,.person,.form,.aside{padding:20px 18px}
  /* On a phone the founders' bios ran in a column beside the avatar for the whole card, which
     left a 78px empty gutter down the left of three paragraphs (Michael, 2026-10-09: "too much
     padding on the left"). Now the avatar shares the top rows with the name and the title, and
     everything under them takes the card's full width. The inner div is display:contents so its
     heading, title and paragraphs are the grid's own items; the markup is unchanged. */
  .people.compact .person{display:grid;grid-template-columns:64px minmax(0,1fr);column-gap:14px;row-gap:0;align-items:center;padding:20px 18px}
  .people.compact .person > div{display:contents}
  .people.compact .person > div > *{grid-column:1/-1}
  .people.compact .person > div > h3{grid-column:2;align-self:end;margin:0}
  .people.compact .person > div > .role{grid-column:2;align-self:start}
  .people.compact .avatar{width:64px;height:64px;border-radius:16px;grid-column:1;grid-row:1/3;align-self:center}
  .cta{padding:36px 20px 36px;border-radius:16px}.cta-mark{width:104px;height:104px;margin-bottom:14px}.cta p{font-size:1rem;margin:12px auto 22px}
  footer{padding:28px 0 40px}
  footer .wrap{flex-direction:column;align-items:flex-start;gap:6px}
  input,select,textarea{font-size:16px}
  .choices span{padding:10px 14px;font-size:.92rem}
  .form button[type=submit]{width:100%}
  .form-note{width:100%;text-align:center}
  /* Wrapped, the note takes the whole line and Send drops below it - so centre the row,
     or space-between leaves a full-width button hugging the left on its own line. */
  .form-send{justify-content:center}
  .form-send .btn{width:100%}
  .contact-grid{margin-top:0;gap:20px}
  .plan .price{font-size:1.2rem}
  .compare{margin-top:24px;border:none;background:transparent;font-size:.93rem}
  .compare thead{display:none}
  .compare tr{display:block;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:12px 14px;margin-bottom:10px}
  .compare td{display:block;padding:0;border:none}
  .compare td:first-child{font-weight:600;color:var(--text);margin-bottom:4px}
  .compare td:empty{display:none}
  .compare td:nth-child(2)::before{content:"Starter \00b7  ";color:var(--gold-dark);font-weight:700}
  .compare td:nth-child(3)::before{content:"Growth \00b7  ";color:var(--gold-dark);font-weight:700}
  .compare td:nth-child(4)::before{content:"Complete \00b7  ";color:var(--gold-dark);font-weight:700}
  .compare td:nth-child(5)::before{content:"Add-on \00b7  ";color:var(--muted);font-weight:700}
  .compare td.all::before{content:"All plans \00b7  ";color:var(--gold-dark);font-weight:700}
  .compare tr.inc td.t:not(.all3){display:none}
  .compare td.all3::before{content:"All plans \00b7  ";color:var(--gold-dark);font-weight:700}
  .compare td:nth-child(2),.compare td:nth-child(3),.compare td:nth-child(4),.compare td.all{text-align:left;white-space:normal}
  .table-wrap{overflow:visible}
  .replaces{margin-top:24px;border:none;background:transparent;font-size:.93rem}
  .replaces thead{display:none}
  .replaces tr{display:block;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:12px 14px;margin-bottom:10px}
  /* the desktop column widths outrank a bare td rule (class + pseudo-class), so they are undone at the same specificity */
  .replaces td,.replaces td:nth-child(1),.replaces td:nth-child(2){display:block;padding:0;border:none;width:auto}
  .replaces td:first-child{font-weight:700;color:var(--text);margin-bottom:6px}
  .replaces td:nth-child(2){margin-bottom:8px}.replaces td:nth-child(2)::before{content:"Today \00b7  ";color:var(--dim);font-weight:700}
  .replaces td:nth-child(3) .yes svg{display:none}.replaces td:nth-child(3)::before{content:"EntertainHQ \00b7  ";color:var(--gold-dark);font-weight:700}
  .replaces td:nth-child(3) .yes{display:inline}
}

/* ---- motion (2026-09-09) ---- */
/* Sections fade and lift in as you reach them and settle back as you leave. Only once
   site.js has put js-ready on <html>; without it the page is simply fully visible. */
/* A section is invisible until you reach it, then fades and lifts in (Michael, 2026-09-09: "not visible until
   you scroll to it ... fade in real nice"); it settles back out when you leave, so it fades in again next time. */
.js-ready section > .wrap,.js-ready .page-head > .wrap{opacity:0;transform:translateY(28px);transition:opacity .9s cubic-bezier(.22,.61,.36,1),transform .9s cubic-bezier(.22,.61,.36,1);will-change:opacity,transform}
.js-ready section.is-visible > .wrap,.js-ready .page-head.is-visible > .wrap{opacity:1;transform:none}
/* Cards rise in once, staggered by site.js through transition-delay. */
/* The stagger rides on --rise-delay rather than transition-delay, because transition-delay
   applies to every property in the list and was delaying hover too (Michael, 2026-09-12). */
.js-ready .reveal{opacity:0;transform:translateY(24px);
  transition:opacity .6s ease var(--rise-delay,0s),transform .6s ease var(--rise-delay,0s)}
.js-ready .reveal.in{opacity:1;transform:none}
/* No scroll snap (2026-09-09): with every section a page, snapping to section tops made scrolling
   "grabby at some spots" (Michael); the glide and the fade carry the feel without it. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .js-ready section > .wrap,.js-ready .page-head > .wrap,.js-ready .reveal{opacity:1!important;transform:none!important;transition:none!important}
  .nav-links a,.nav-links a::after,.nav-links,.nav-links > *,.menu-btn .bar{transition:none}
  .btn:hover{transform:none}
  .chapters a,.chapters a::after,.chapters button,.chapters button::after{transition:none}.chapters a:hover,.chapters button:hover{transform:none}
  .tabs.moving,.panel,.plans-top .billing{transition:none}
  .tier .price .amt,.tier .price .per{transition:none}.tier .price .amt .fig,.tier .price .amt .out{animation:none}
}

@property --bleed  { syntax:"<length>"; inherits:true; initial-value:0px }
@property --mx     { syntax:"<length>"; inherits:true; initial-value:0px }
@property --my     { syntax:"<length>"; inherits:true; initial-value:8px }
@property --over-l { syntax:"<length>"; inherits:true; initial-value:80px }
@property --over-r { syntax:"<length>"; inherits:true; initial-value:260px }

/* The comparison (2026-09-11): pick the products you run, see what they leave you doing by hand.
   Circles, not ticks: full, half and empty is the shape of the data, and a cross reads as a verdict
   on a company rather than a fact about a feature. */
/* the picker is the first thing in the panel now, so the tab strip's own gap is the whole gap */
/* The comparison table (2026-09-11). Circles, not ticks: full, half and empty is the shape of the
   data, and a cross reads as a verdict on a company rather than a fact about a feature.
   Restored 2026-09-12. The cut that removed the picker ran past its own end and took the map, the
   table, the marks and the legend with it, so every mark lost its width and the legend's first dot
   drew at the width of the page. The picker's rules are deliberately NOT back; this is the table. */
/* No heading above it any more (Michael, 2026-09-12), so the 44px that sat under one would
   be a band of nothing at the top of the section. The section's own padding does that job. */
.cmp-map{margin-top:0}
/* The site lets a table wrapper overflow visibly on a phone, which is right for the three column
   table that rule was written for and wrong for a wide one: it pushed the whole PAGE sideways at
   390px. Two classes deep so it outranks that rule, and hung on .cmp-map itself because a previous
   rewrite of a neighbouring block already silently took this line once. */
.cmp-map .table-wrap{overflow:auto}
.cmp-table{width:100%;border-collapse:separate;border-spacing:0;font-size:.9rem;background:var(--panel);
  border:1px solid var(--line);border-radius:12px}
/* Middle, not top: top was right when a cell held a mark with a note under it, and wrong now
   that a cell holds nothing but the mark (Michael, 2026-09-12). It centres the row label
   against its own dots as well. */
.cmp-table th,.cmp-table td{padding:6px 7px;border-bottom:1px solid var(--line);text-align:center;vertical-align:middle}
/* The body row height is STATED, not left to whatever happens to be in the cell. Each label
   carried a price line under it until 2026-09-14; taking that away (Michael: "remove the dollar
   figures from this") dropped the rows from 59px to 36px and the table from 342 to 227, which
   reads as cramped against the nine columns beside it (Michael, 2026-09-14: "make the rows go
   back to [the height] they were"). Stated here it survives the next content change as well.
   Measured, not derived: 59px reproduces the pre-2026-09-14 table. */
.cmp-table tbody th[scope="row"],.cmp-table tbody td{height:59px}
/* No fill on the header (Michael, 2026-09-12). It was #f8f6f1 against our own row's #f7f1e4,
   near enough the same wash that the one meant to single us out was competing with it. One
   tinted row in the table now, and it is ours. Without a fill the header needs a line to stand
   on, hence the heavier rule. Its own padding too: the body cells went to 6px to keep the rows
   tight and the header should never have gone with them, being the row that frames the rest. */
.cmp-table thead th{position:sticky;top:0;background:var(--panel);color:var(--muted);font-size:.7rem;letter-spacing:.09em;
  text-transform:uppercase;font-weight:700;text-align:center;padding:14px 7px;border-bottom:1px solid var(--line-2)}
/* One line each, centred over their dots. The cap existed to break long headings over two or
   three lines, which is what made the row a mess (Michael, 2026-09-12); the labels are short
   enough now that the right answer is simply not to wrap them. */
.cmp-table thead th span{display:block;white-space:nowrap;margin:0 auto}
.cmp-table th[scope="row"]{position:sticky;left:0;z-index:1;background:var(--panel);text-align:left;font-weight:700;
  color:var(--text);white-space:nowrap;border-right:1px solid var(--line)}
.cmp-table thead th:first-child{left:0;z-index:2;text-align:left}
.cmp-table td i{display:block;margin-top:4px;font-style:normal;font-size:.76rem;line-height:1.35;color:var(--dim)}
/* A cell that holds only a mark has no text in it, so it carries no line height for the mark
   to sit on top of. The row labels and the headings are text and keep theirs. */
.cmp-table td{line-height:0}
/* Our row is the only tinted one, and in dark --gold-soft is rgba(232,213,175,.09) - 9 percent
   alpha, measured. On the TD that is fine, it sits on the table's own panel and composites to the
   warm lift it is meant to be. On the row label it is not: that cell is position:sticky, so every
   column scrolls UNDERNEATH it, and a 91 percent transparent cell shows all of it (Michael,
   2026-09-15: "the dots when scrolling are bleeding in the tools"). Only our row did it; every
   other label cell is --panel, which is solid.
   So the sticky cell composites the tint onto an opaque panel ITSELF, in one declaration: the
   background-color of a shorthand paints beneath its layers, so this is gold-soft over panel,
   which is exactly what the cell already looked like with nothing behind it. Light mode is
   unchanged either way, --gold-soft being opaque there.
   The rule for the next translucent token: a sticky, fixed or floating element cannot carry one
   as its only background. Something scrolls under everything that stays still. Swept rather than
   patched: every other position:sticky / position:fixed rule in this file is on --panel, which is
   solid in both themes. The one exception is .nav on --nav-glass, and that is the point of it -
   86 percent alpha with a backdrop blur behind it, so what shows through is a wash, not shapes. */
.cmp-table tr.us td{background:var(--gold-soft)}
.cmp-table tr.us th[scope="row"]{background:linear-gradient(var(--gold-soft),var(--gold-soft)),var(--panel)}
/* Known, and deliberately left alone: <thead> holds exactly ONE <tr>, so this bare
   tr:last-child matches the HEADER row as well as the last body row. Same specificity as
   the thead rule above and later in the file, so it wins, and the header has never drawn
   the "heavier rule" its own comment describes. Scoping this to tbody restores that line
   and changes how the table looks, which is not wanted (Michael, 2026-09-14: "lets just
   go back to what we had"). Written down so the next person does not rediscover it. */
.cmp-table tr:last-child th,.cmp-table tr:last-child td{border-bottom:0}
/* The width here is load-bearing: an inline svg with no size takes the width of its container, so
   losing these two lines is what drew a circle the size of the page. */
/* 19px: a fifth up from the 16 these started at (Michael, 2026-09-12, after 24 was too big).
   A whole pixel because a fractional one renders the circle soft, and 19.2 was the sum.
   The legend is not a separate size: its marks are these same marks, so this moves both. */
.cmp-m{display:inline-block;width:19px;height:19px;line-height:0;vertical-align:middle}
.cmp-m svg{width:19px;height:19px;display:block}
.cmp-m.full{color:var(--gold-dark)}
.cmp-m.part{color:var(--gold)}
.cmp-m.none{color:var(--line-2)}
.cmp-m .ring{fill:none;stroke:currentColor;stroke-width:1.6}
.cmp-m svg circle:not(.ring),.cmp-m svg path{fill:currentColor}
.cmp-legend{margin:0 0 12px;color:var(--dim);font-size:.84rem;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.cmp-legend .cmp-m{margin-left:10px}
.cmp-legend .cmp-m:first-child{margin-left:0}
@media (max-width:700px){
  .cmp-table th,.cmp-table td{padding:10px 11px}
}

/* Every press is 44px on a phone (2026-09-11). A sweep at 390px found thirty-one under it: tabs and
   buttons at 43, the hamburger at 40, the logo at 34, each styled by hand with its own padding. One
   rule beats thirty patches, and a control that must be smaller has to argue with it. A link inside
   a sentence is exempt on purpose: a 44px email address in running text is worse.
   Restored 2026-09-12 with the block above; it was never part of the picker and should not have
   gone with it. The two chip selectors it used to name are dropped, because those are really gone. */
@media (max-width:640px){
  .nav-links a,.btn,.menu-btn,.logo,.chapters button,.chapters a,
  .billing button,button[type=submit],input[type=submit]{min-height:44px}
  .btn,.chapters button,.billing button{display:inline-flex;align-items:center;justify-content:center}
  .nav-links a,.logo{display:flex;align-items:center}
}

/* Compare is for a computer (Michael, 2026-09-12: "on mobile remove the compare section"), which
   started as the map alone and is now the whole section. Thirteen products by ten columns has no
   honest phone layout: as a table it is a postage stamp you drag around, and as blocks it is
   thirteen screens of scrolling. The link goes with the section, or the nav points at nothing. */
@media (max-width:760px){
  #compare{display:none}
  .nav-links a[href="#compare"]{display:none}
}

/* ---- section lines: spacing, and it must live HERE -------------------------------------
   These were first written up beside .sec-line itself and silently lost: .faq-group
   {margin-top:34px} and .contact-grid{gap:28px} are the same specificity (0,1,0) and sit
   several hundred lines further down, so source order decided it and the six headings came
   out with three different gaps - 30, 34 and 28. Equal specificity means LAST wins, so the
   overrides belong at the end of the sheet, not next to the thing they describe.

   The line's own margin-bottom is the only source of the gap beneath it; whatever follows
   must not add a second. One rule rather than a patch per section, so a section added later
   inherits it. */
.sec-line + *{margin-top:0}
/* Contact's wrap IS the two-column grid, so the line is a grid item: span both columns and
   let the row gap space it, since a margin inside a grid row would stack with that gap. */
.contact-grid > .sec-line{grid-column:1/-1;margin-bottom:0}
.contact-grid{row-gap:30px}

/* The legal pages (2026-10-20): /terms and /privacy, built by scripts/site_legal_pages.py from docs/legal/.
   Reading width, numbered sections, the markdown's tables at phone width without sideways scroll. */
.legal .wrap{max-width:820px}
.legal .lede{color:var(--muted);font-size:1.1rem;margin-top:14px;max-width:60ch}
.legal-date{color:var(--dim);font-size:.9rem;margin-top:10px}
.legal-body{margin-top:34px;font-size:1rem;color:var(--text)}
.legal-body h2{font-size:1.35rem;margin-top:40px;padding-top:22px;border-top:1px solid var(--line)}
.legal-body h3{margin-top:26px}
.legal-body p,.legal-body li{margin-top:12px;color:var(--muted);line-height:1.65}
.legal-body li{margin-top:6px}
.legal-body ul,.legal-body ol{padding-left:22px;margin:0}
.legal-body strong{color:var(--text)}
.legal-body a{color:var(--gold-dark);text-decoration:underline;text-underline-offset:2px}
.legal-body code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.92em;background:var(--gold-soft);padding:1px 5px;border-radius:5px;word-break:break-all}
.legal-body hr{border:0;border-top:1px solid var(--line);margin:34px 0}
.legal-body table{width:100%;border-collapse:collapse;margin-top:16px;font-size:.93rem;display:block;overflow-x:auto}
.legal-body th,.legal-body td{text-align:left;vertical-align:top;padding:10px 12px;border-bottom:1px solid var(--line);color:var(--muted);min-width:9em}
.legal-body th{color:var(--text);font-weight:700;background:var(--bg-2)}
.legal-body td:first-child,.legal-body th:first-child{min-width:11em}
.legal-body td{word-break:normal;overflow-wrap:anywhere}
/* The footer's two links (Michael, 2026-10-20: the terms and the privacy policy on every page). */
.foot-links{display:flex;gap:18px}
.foot-links a{color:var(--dim)}
.foot-links a:hover{color:var(--text)}
/* The line under the contact form: what you type here goes to us under the privacy policy. */
.form-legal{color:var(--dim);font-size:.84rem;margin-top:10px}
.form-legal a{text-decoration:underline;text-underline-offset:2px}

/* #195 (2026-10-30): buying leads, the iPhone app has its own section. */
.hero-note{margin-top:14px;font-size:.92rem;color:var(--muted)}
.hero-note a,.buy-note a{color:inherit;text-decoration:underline;text-underline-offset:3px}
.buy-note{margin:22px auto 0;max-width:72ch;text-align:center;font-size:.95rem;color:var(--muted)}
/* The hero's devices (2026-10-31, Michael: "make a phone show up along side the browser view on the hero page. And a
   sneaky little link to the app store app right there"): the app in a browser window, and the iPhone app overlapping its
   lower right corner; under the window, the App Store's own badge. The phone's screens are the iPhone app on the same
   six pages as the window, in the same cell and the same crossfade, and site.js turns both at once (Michael, 2026-10-31:
   "the rotates need to happen at the same time"). The phone's frame and status bar are drawn here, so they follow the
   theme with the screen. */
/* #251 (Michael, 2026-11-05: "It's too low. Basically, take where it's at now and scoot it up and shift it over a little
   bit"): the phone hangs a little below the window, not a third of itself, and on a wide screen stands a little further
   out to the right. */
.devices{position:relative;padding-bottom:16px}
.devices .window{margin-right:12%}
.phone{position:absolute;right:0;bottom:38px;width:30%;min-width:132px;max-width:230px;padding:7px;border-radius:40px;
  background:#101113;border:1px solid #2c2d31;box-shadow:0 40px 70px -28px rgba(16,24,40,.55),0 2px 8px rgba(16,24,40,.18)}
.phone-screen{position:relative;display:grid;aspect-ratio:1206/2622;border-radius:33px;overflow:hidden;background:var(--phone-bar);container-type:inline-size}
.phone-screen > .pshot{grid-area:1/1;opacity:0;visibility:hidden;transition:opacity .55s ease,visibility 0s linear .55s}
.phone-screen > .pshot.on{opacity:1;visibility:visible;transition:opacity .55s ease}
@media (prefers-reduced-motion:reduce){
  .phone-screen > .pshot{transition:none}
}
.phone-screen img.th-l,.phone-screen img.th-d{width:100%;height:auto}
/* The status bar covers the screens' own (62 of the iPhone's 874 points), laid out as the iPhone's is. */
.phone-bar{position:absolute;z-index:1;top:0;left:0;right:0;height:7.1%;display:flex;align-items:center;justify-content:space-between;
  padding:0 9% 0 14%;background:var(--phone-bar);color:var(--text);font-size:.62rem;font-size:4.2cqw;font-weight:700;
  letter-spacing:.01em;font-variant-numeric:tabular-nums}
.phone-bar .island{position:absolute;top:22%;left:50%;transform:translateX(-50%);width:31%;height:58%;border-radius:999px;background:#000}
.phone-bar .phone-icons{width:15%;width:19.4cqw;height:auto}
@media (min-width:1100px){.phone{right:-24px}}
/* The two stores' own badges side by side (#251). Google's carries its own clear space, 41 of its 250 pixels on every
   side: drawn 60px tall its artwork is the App Store badge's 40, and the negative margin gives the clear space back so
   the two line up. */
.app-links{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:22px}
.app-link{display:inline-flex}
.app-link img.th-l,.app-link img.th-d{width:120px;height:auto;flex:none}
.app-link-play img{width:auto;height:60px;margin:-10px;flex:none}
:root{--phone-bar:#fefefe}
:root[data-theme="dark"]{--phone-bar:#171717}
@media (max-width:600px){
  .devices{padding-bottom:12px}
  .devices .window{margin-right:16%}
  .phone{width:38%;padding:5px;border-radius:30px}
  .phone-screen{border-radius:25px}
  .phone{bottom:30px}
  .app-links{margin-top:18px;gap:10px}
  .app-link img.th-l,.app-link img.th-d{width:108px}
  .app-link-play img{height:54px;margin:-9px}
}
/* Side by side, the two badges run under the phone on a narrow phone (320 to 480): there they stand one above the
   other, left of it, and the phone rises by the extra row so it still hangs just below the window. */
@media (max-width:480px){
  .app-links{flex-direction:column;align-items:flex-start}
  .phone{bottom:76px}
}
