/* Nudge · site styles. Tokens, layout, working files, viewfinder, motion. No webfonts, by brand rule. */

:root{
  --ground:#011C1A;--surface:#022624;--teal:#1CAEA0;--cream:#FCEE9E;
  --c80:rgba(252,238,158,.8);--c60:rgba(252,238,158,.6);--c50:rgba(252,238,158,.5);--c40:rgba(252,238,158,.4);--c20:rgba(252,238,158,.2);--c10:rgba(252,238,158,.1);--c05:rgba(252,238,158,.05);
  --t60:rgba(28,174,160,.6);--t30:rgba(28,174,160,.3);--t12:rgba(28,174,160,.12);
  --red:#E05252;--amber:#E8A830;--green:#3ABF7A;
  --sans:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;
  --ease:cubic-bezier(.76,0,.24,1);
  --fw:380px;--fh:380px;
  box-sizing:border-box;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px)
}
html{scroll-padding-top:env(safe-area-inset-top,0px)}
*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--ground);color:var(--c80);font-family:var(--sans);font-weight:500;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden}
img,svg{max-width:100%}
a{color:inherit}
button{font:inherit;cursor:pointer;color:inherit}
h1,h2,h3{font-weight:900;text-transform:uppercase;line-height:1;color:var(--cream);letter-spacing:-.02em}
h1{letter-spacing:-.05em}
.dot{color:var(--teal)}
.mono{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60)}
.shell{max-width:1280px;margin:0 auto;padding:0 clamp(20px,4.5vw,64px)}
:focus-visible{outline:2px solid var(--teal);outline-offset:3px}
.skip{position:absolute;left:-9999px;top:0;z-index:100}
.skip:focus{left:12px;top:12px;background:var(--cream);color:var(--ground);padding:10px 16px;border-radius:2px;font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;text-decoration:none}
::selection{background:var(--teal);color:var(--ground)}

/* ---------- signature device ---------- */
.device{position:fixed;left:0;right:0;top:34vh;height:25vh;overflow:hidden;pointer-events:none;z-index:0}
.device span{position:absolute;white-space:nowrap;font-weight:900;font-size:25vh;line-height:1;text-transform:uppercase;letter-spacing:-.04em;color:transparent;-webkit-text-stroke:1px var(--c05);animation:drift 120s linear infinite}
@keyframes drift{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media(max-width:760px){.device{height:15vh;top:40vh}.device span{font-size:15vh}}
@media(prefers-reduced-motion:reduce){.device span{animation:none}}

/* ---------- page ---------- */
#page{position:relative;z-index:1}
.nav{display:flex;justify-content:space-between;align-items:center;padding:26px 0;gap:20px}
.lockup{display:block;height:34px;width:auto}
.nav ul{display:flex;gap:28px;list-style:none;font-size:14px;color:var(--c60)}
.nav ul a{text-decoration:none}.nav ul a:hover{color:var(--teal)}
@media(max-width:920px){.nav ul{display:none}}
/* Phone and tablet navigation. Below 920px the desktop list is hidden, so the same four
   destinations live in a native <details> drawer: no script, so it cannot become a dead
   control, and the disclosure state is announced without any ARIA of our own. */
.navdrawer{display:none;position:relative}
@media(max-width:920px){.navdrawer{display:block;margin-left:auto}}
/* THE STICKY CTA FITS ON A PHONE. It did not: "START A SIGNAL AUDIT" was painted as "START A
   SIGNAL AU" on every page at every phone width, because .btn sets white-space:nowrap and also
   overflow:hidden for the hover sweep, so the label was cut instead of spilling where anybody
   would have noticed it. 479px is measured, not chosen: the label needs 183px and the nav has
   exactly 183px to give at a 480px viewport, 161px at 430, 141px at 390 and 105px at 320.
   Letting it wrap rather than renaming it means this holds for all three labels the site uses
   ("Start a Signal Audit", "Run the Pulse Check", "Write to us") and for the next one, and the
   words a screen reader announces stay the words on the screen. The nav gap comes down to buy
   the label room first, so it wraps to two lines rather than three. */
@media(max-width:479px){
  .nav{gap:12px}
  /* The wordmark gives way first, within a floor. Flex shares a shortage in proportion to base
     width, so the widest item - the CTA - was losing the most, which is backwards: the wordmark
     stays recognisable at half size and a cut label does not. 72px is measured: it is the largest
     wordmark that still leaves the CTA enough for TWO lines at 320px rather than three, and it is
     larger than the 59px the wordmark was squeezed to on the same screen before this. */
  .nav>a:first-child{flex-shrink:4;min-width:72px}
  .nav .btn.ghost{white-space:normal;text-align:center;line-height:1.3;padding:9px 12px;letter-spacing:.05em;min-width:0}
}
.nav .navdrawer>summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--c60);border:1px solid var(--c20);border-radius:2px;padding:10px 14px;transition:color .3s,border-color .3s}
.nav .navdrawer>summary::-webkit-details-marker{display:none}
.nav .navdrawer>summary::marker{content:""}
.nav .navdrawer>summary::after{content:"+";font-size:13px;line-height:1}
.nav .navdrawer[open]>summary{color:var(--teal);border-color:var(--teal)}
/* U+2212 MINUS SIGN, not an ASCII hyphen. Measured in this button's own font at 11px: all
   three glyphs are the same width, but the plus above draws its crossbar on row 24 and the
   minus sign lands on row 24 too, while "-" sits on row 25. One pixel, and the two swap in
   place when the menu opens, so the hyphen reads as the glyph dropping.
   THE ESCAPE MUST NOT BE FOLLOWED BY A HEX DIGIT OR A SPACE THAT IS MEANT TO BE KEPT. CSS
   reads up to six hex digits after a backslash, so \2212 then a digit is one different
   character, and a terminating space is swallowed. Here the closing quote ends it.
   This line previously held U+0091 and a literal 2, which draws nothing, so the button read
   "Menu 2". scripts/check-control-chars.mjs is what now notices. */
.nav .navdrawer[open]>summary::after{content:"\2212"}
.nav .navdrawer>ul{display:flex;flex-direction:column;gap:0;position:absolute;right:0;top:calc(100% + 12px);z-index:40;min-width:210px;list-style:none;background:var(--surface);border:1px solid var(--c10);border-radius:2px;padding:6px 0;font-size:14px}
.nav .navdrawer>ul a{display:block;padding:12px 18px;text-decoration:none;color:var(--c80)}
.nav .navdrawer>ul a:hover{color:var(--teal)}
.nav .navdrawer>ul a[aria-current=page]{color:var(--cream)}

.btn{display:inline-flex;align-items:center;gap:10px;background:var(--cream);color:var(--ground);border:1px solid var(--cream);border-radius:2px;padding:13px 22px;font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;text-decoration:none;transition:background .3s,border-color .3s,color .3s;white-space:nowrap}
.btn:hover{background:var(--teal);border-color:var(--teal)}
.btn.ghost{background:transparent;color:var(--cream);border-color:var(--c20)}
.btn.ghost:hover{border-color:var(--teal);color:var(--teal);background:transparent}
.btn kbd{font-family:var(--mono);border:1px solid currentColor;border-radius:2px;padding:1px 5px;font-size:10px}

.hero{min-height:calc(100vh - 90px);display:grid;align-content:center;padding:4vh 0 8vh;gap:0}
.hero h1{font-size:clamp(2.1rem,4.7vw,4.5rem);max-width:19ch}
@media(min-height:1000px){.hero h1{font-size:clamp(2.1rem,5.4vw,5.4rem)}}
.qcarry{margin-top:16px;padding:14px 16px;background:var(--ground);border:1px solid var(--c10);border-radius:2px;font-family:var(--mono);font-size:11px;line-height:1.7;color:var(--c60);white-space:pre-wrap;max-height:220px;overflow:auto}
.qcarry b{color:var(--teal);font-weight:500;display:block;margin-bottom:6px;letter-spacing:.06em;text-transform:uppercase}
.sendbox{border:1px solid var(--c10);border-radius:2px;background:var(--surface);padding:22px 24px}
.rub-live{display:inline-block;margin-top:10px;font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;padding:4px 9px;border:1px solid var(--c10);border-radius:2px;color:var(--c60)}
.rub-live.ok{color:var(--green);border-color:rgba(58,191,122,.35)}.rub-live.warn{color:var(--amber);border-color:rgba(232,168,48,.35)}.rub-live.bad{color:var(--red);border-color:rgba(224,82,82,.35)}
.redact{cursor:help;transition:background .3s}.redact:hover{background:var(--teal)}
/* ===== capabilities: tools and price tiers ===== */
.tool{border:1px solid var(--c10);border-radius:2px;background:var(--surface);padding:clamp(20px,3vw,34px);margin-top:34px}
.toolrow{display:grid;grid-template-columns:1fr 1fr;gap:clamp(18px,3vw,36px)}
@media(max-width:760px){.toolrow{grid-template-columns:1fr}}
.tool label{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60);margin:0 0 8px}
.tool input[type=text],.tool input[type=number],.tool textarea{width:100%;background:var(--ground);border:1px solid var(--c10);border-radius:2px;color:var(--cream);font-family:var(--mono);font-size:13px;line-height:1.6;padding:12px 14px}
.tool input:focus,.tool textarea:focus{outline:none;border-color:var(--teal)}
.tool .toolrow>div{min-width:0}
.tool .stat b{font-size:clamp(2rem,4vw,3rem);font-weight:900;color:var(--cream);letter-spacing:-.03em;margin-right:8px}
.tool .say{font-size:1.1rem;line-height:1.6;color:var(--cream);max-width:62ch;word-break:break-word}
.tool .miss{margin-top:8px;list-style:none}.tool .miss li{padding:8px 0;border-top:1px solid var(--c05);color:var(--c60);font-size:.95rem}.tool .miss b{color:var(--cream)}
.tool .words{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}.tool .words span{border:1px solid var(--c10);border-radius:9999px;padding:6px 12px;font-family:var(--mono);font-size:12px;color:var(--cream);word-break:break-word}.tool .words i{color:var(--teal);font-style:normal;margin-left:4px}.tool .words .none{color:var(--c60)}
.cmpscore{color:var(--teal);font-family:var(--mono);font-weight:500}.cmpscore b{font-size:1.5rem;font-weight:900;color:var(--cream)}
.cmpwrap{position:relative;height:clamp(320px,46vh,460px);overflow:hidden;border:1px solid var(--c10);border-radius:2px;background:var(--ground);cursor:ew-resize;touch-action:pan-y;user-select:none}
.cmppane{position:absolute;inset:0;padding:22px 24px;overflow:hidden}
.cmppane.top{background:var(--surface);clip-path:inset(0 var(--cut,50%) 0 0);border-right:2px solid var(--teal)}
.cmphead{display:flex;justify-content:space-between;gap:20px;margin-bottom:14px}
.cmphead>div{display:flex;flex-direction:column;gap:4px}.cmphead>div[data-h=new]{text-align:right;align-items:flex-end}
.cmphead .cmpscore b{font-size:clamp(1.8rem,3.4vw,2.6rem)}
.cmppane .pt{font-family:var(--mono);font-size:12px;line-height:1.75;color:var(--c60);word-break:break-word}
.cmppane.top .pt{max-width:30ch;color:var(--cream)}
.cmpgrip{position:absolute;top:50%;left:calc(100% - var(--cut,50%));width:34px;height:34px;margin:-17px 0 0 -17px;border-radius:9999px;background:var(--teal);pointer-events:none}
.cmprange{width:100%;margin-top:16px;accent-color:#1CAEA0}
.ask .askrow{display:flex;gap:10px}.ask .askrow input{flex:1}
.cutp{font-size:clamp(1.05rem,1.4vw,1.25rem);line-height:1.7;color:var(--cream);max-width:64ch;min-height:7.5em}
.tiers{margin-top:22px}.tiers>div{display:flex;justify-content:space-between;align-items:baseline;gap:16px;padding:14px 0;border-top:1px solid var(--c10)}
.tiers b{color:var(--cream);font-weight:700}.tiers p{font-size:.9rem;line-height:1.55;color:var(--c60);margin-top:4px}.tiers>div>span{font-family:var(--mono);font-size:12px;color:var(--teal);white-space:nowrap;text-align:right}
.caps{list-style:none;margin-top:38px;border-top:1px solid var(--c10)}
.caps li{display:grid;grid-template-columns:44px 1.25fr 1.1fr 150px;gap:clamp(14px,2.4vw,32px);align-items:start;padding:26px 0;border-bottom:1px solid var(--c10)}
.caps .n{font-family:var(--mono);font-size:11px;color:var(--teal);padding-top:6px}
.caps .cap a{color:var(--cream);text-decoration:none;font-weight:900;text-transform:uppercase;letter-spacing:-.02em;font-size:clamp(1.3rem,2.2vw,1.9rem);line-height:1}
.caps .cap a:hover{color:var(--teal)}.caps .cap p{margin-top:10px;color:var(--c80);font-size:1rem;line-height:1.6}
.caps .proof p{color:var(--c60);font-size:.95rem;line-height:1.6;margin-top:6px}.caps .proof a,.caps .proof button{color:var(--teal);background:none;border:0;padding:0;font:inherit;cursor:pointer;text-decoration:underline;text-underline-offset:4px}
.caps .from{text-align:right}.caps .from b{display:block;color:var(--cream);font-weight:900;font-size:1.3rem;letter-spacing:-.02em;margin-top:6px}.caps .from small{display:block;font-family:var(--mono);font-size:10.5px;color:var(--c60);margin-top:4px}
@media(max-width:860px){.caps li{grid-template-columns:34px 1fr}.caps .proof,.caps .from{grid-column:2}.caps .from{text-align:left}}
.notebody{max-width:66ch}.sec .notebody h2{font-size:clamp(1.5rem,2.4vw,2.2rem);margin-top:52px;max-width:none;letter-spacing:-.02em}.sec .notebody h2:first-child{margin-top:0}.sec .notebody .sub{margin-top:14px;max-width:none}
.lede{font-size:clamp(1.05rem,1.35vw,1.2rem);line-height:1.65;max-width:58ch;margin-top:26px;color:var(--c80)}
.ctas{display:flex;flex-wrap:wrap;gap:14px;align-items:center;margin-top:34px}
.ctas .alt{font-size:14px;color:var(--c60);text-decoration:underline;text-underline-offset:5px;text-decoration-color:var(--c20)}
/* The second hand-off on a Pulse result. The lead-in is not a link, so only the two page
   names are underlined and the separator between them is not. */
/* The line that leads into the routed next step. It takes the whole row so the sentence sits
   ABOVE the button it introduces rather than beside it, which is the difference between leading
   in and interrupting. It REPLACES .fixnext, the two-door line from #36: that markup offered
   both pages and is gone, so its rules go with it rather than sitting here unused.

   THE BOX GETS THE ROW AND THE TEXT GETS THE MEASURE, in two rules rather than one, because one
   does not work. A max-width on the flex item clamps its hypothetical main size, which is the
   size flex uses to decide where a line breaks, so a 56ch cap on a 1165px row left the item
   435px wide and the button sat beside it. Measured, not guessed: flex:0 0 100% alone did not
   fix it either, for the same reason. The reading measure therefore lives on the span inside. */
.ctas .fixwhy{flex:0 0 100%;margin:0;font-size:14px;line-height:1.55;color:var(--c60)}
.ctas .fixwhy span{display:block;max-width:56ch}
/* On a phone the two offers wrapped mid-phrase, so the middle dot stopped separating anything.
   Each gets its own line below 600px and the dot goes, because a separator between two things on
   different lines is not separating them. */
/* It is already full-width at every size, so it needs no phone rule of its own. The audit link
   under it does: demoted to text it must not sit on the button's baseline on a narrow screen. */
@media(max-width:600px){.ctas .alt{flex-basis:100%}}
.ctas .alt:hover{color:var(--teal)}
.proofline{margin-top:56px;display:flex;flex-wrap:wrap;gap:8px 26px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60);padding-top:18px;border-top:1px solid var(--c10);max-width:820px}
.proofline b{color:var(--cream);font-weight:500}
.proofline a,.proofline button{color:var(--teal);text-decoration:none;cursor:pointer;border:0;background:none;padding:0;font:inherit;letter-spacing:inherit;text-transform:inherit}
.proofline a:hover,.proofline button:hover{text-decoration:underline;text-underline-offset:4px}

section.sec{padding:clamp(80px,11vh,140px) 0;border-top:1px solid var(--c10)}
.sec h2{font-size:clamp(2.2rem,5vw,4.6rem);max-width:15ch}
.sec .sub{max-width:60ch;margin-top:22px;font-size:1.05rem}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:clamp(30px,5vw,80px);align-items:start}
@media(max-width:860px){.grid2{grid-template-columns:1fr}}
.pattern{list-style:none;margin-top:10px}
.pattern li{padding:22px 0;border-bottom:1px solid var(--c10);display:grid;grid-template-columns:auto 1fr;gap:20px;align-items:start;font-size:1.05rem}
.pattern li:last-child{border-bottom:0}
.pattern .n{font-family:var(--mono);font-size:11px;color:var(--teal);padding-top:8px;letter-spacing:.08em}
.pattern b{display:block;color:var(--cream);font-weight:700;margin-bottom:4px}
.pattern .q{display:block;margin-top:10px;font-size:.95rem;color:var(--c60)}
.pattern .q::before{content:'“'}.pattern .q::after{content:'”'}

.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--c10);margin-top:44px;border:1px solid var(--c10);border-radius:2px;overflow:hidden}
@media(max-width:860px){.steps{grid-template-columns:1fr}}
.steps article{background:var(--ground);padding:34px 30px 38px;display:flex;flex-direction:column}
.steps article p{flex:1}
.steps .out{margin-top:auto;padding-top:16px}
.steps .k{font-family:var(--mono);font-size:11px;letter-spacing:.08em;color:var(--teal);text-transform:uppercase}
.steps h3{font-size:2.4rem;margin:16px 0 14px}
.steps p{font-size:1rem}
.steps .out{margin-top:24px;border-top:1px solid var(--c10);font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60);line-height:1.8}
.steps .out b{color:var(--c80);font-weight:500}

/* self audit */
.rubric{margin-top:44px;border:1px solid var(--c10);border-radius:2px;background:var(--surface)}
.rubric header{display:flex;justify-content:space-between;align-items:center;gap:20px;padding:20px 26px;border-bottom:1px solid var(--c10);flex-wrap:wrap}
.rubric header .mono b{color:var(--cream);font-weight:500}
.rubric .score{font-weight:900;font-size:2.2rem;color:var(--cream);letter-spacing:-.03em}
.rubric .score i{font-style:normal;color:var(--teal)}
.rubric table{width:100%;border-collapse:collapse}
.rubric th{padding:12px 26px;border-bottom:1px solid var(--c10);text-align:left;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60);font-weight:500}
.rubric th:last-child{text-align:right}
.rubric td{padding:16px 26px;border-bottom:1px solid var(--c05);vertical-align:top;font-size:.98rem}
.rubric tr:last-child td{border-bottom:0}
.rubric td.chk{width:150px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60)}
.rubric td.res{width:130px;text-align:right;font-family:var(--mono);font-size:12px;white-space:nowrap}
.rubric td.res.ok{color:var(--green)}.rubric td.res.warn{color:var(--amber)}.rubric td.res.bad{color:var(--red)}
.rubric td.res small{display:block;color:var(--c60);font-size:10px;text-transform:uppercase;letter-spacing:.06em;margin-top:3px}
.rubric .note{padding:18px 26px;border-top:1px solid var(--c10);font-size:.95rem;color:var(--c60)}
/* The check-name column is hidden on a phone, and so is ITS HEADER. Hiding the body cell and
   leaving the <th> behind kept a third column with nothing in it, labelled "Check" for a column
   that was not there, and at 26px of padding on each side that phantom column is what held the
   table at 306px minimum on a 320px screen. The header padding comes down to match the body's,
   which it never did. */
@media(max-width:700px){.rubric td.chk,.rubric thead th:first-child{display:none}.rubric td{padding:14px 18px}.rubric th{padding:12px 18px}}

.offer{display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(30px,5vw,80px);align-items:start}
@media(max-width:860px){.offer{grid-template-columns:1fr}}
.faq dt{color:var(--cream);font-weight:700;font-size:1.15rem;margin-top:28px}
.faq dd{margin-top:8px;font-size:1rem}
.price{font-weight:900;font-size:clamp(3rem,7vw,6.2rem);color:var(--cream);line-height:.95;letter-spacing:-.04em}
.price i{font-style:normal;color:var(--teal)}
.price + p{margin-top:18px;color:var(--c60)}
.pricebox{border:1px solid var(--c10);border-radius:2px;padding:34px 32px;background:var(--surface)}
/* A PRICE CARD ON A PHONE. Its own padding was 64px of a 320px screen, and the pieces inside it
   could not shrink: .btn is nowrap site-wide, which is right for "Send it" and wrong for "Write
   to us about content or film", and a .tiers row is a flex pair whose minimum is both sides plus
   the gap however narrow the screen gets. Those three together are what made four pages drag
   sideways, not the question lists the audit saw moving. 479px is the same phone breakpoint the
   nav CTA uses; the tier rows stack only below 340px, because a pair needs 283px once the box
   padding comes down and a 340px screen has 300px to give, so at 360 and 390 they stay side by
   side exactly as the audit passed them. */
@media(max-width:479px){
  .pricebox{padding:24px 20px}
  .pricebox .btn{white-space:normal;text-align:center;line-height:1.35;justify-content:center}
  .sendbox .btn{white-space:normal;text-align:center;line-height:1.35;justify-content:center}
}
@media(max-width:339px){
  .tiers>div{flex-direction:column;align-items:flex-start;gap:6px}
  .tiers>div>span{text-align:left}
}

.founders{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--c10);border:1px solid var(--c10);border-radius:2px;overflow:hidden;margin-top:44px}
@media(max-width:700px){.founders{grid-template-columns:1fr}}
.founders article{background:var(--ground);padding:34px 30px;display:grid;grid-template-columns:auto 1fr;gap:24px;align-items:start}
.avatar{width:84px;height:84px;border-radius:9999px;border:1px solid var(--c20);display:grid;place-items:center;font-weight:900;font-size:2rem;color:var(--teal)}
.founders .k{font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--teal)}
.founders h3{font-size:2rem;margin:6px 0 10px}
.founders p{font-size:1rem}

.teal{background:var(--teal);color:var(--ground);border-top:0;margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw)}
.teal h2,.teal .k{color:var(--ground)}
.teal .sub{color:rgba(1,28,26,.8)}
.teal .k{font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;margin-bottom:18px;font-weight:700}
.pulse{display:grid;grid-template-columns:1fr auto;gap:0;margin-top:34px;max-width:760px;border-bottom:2px solid var(--ground)}
.pulse input{background:transparent;border:0;outline:0;color:var(--ground);font-weight:900;font-size:clamp(1.6rem,3.6vw,3rem);text-transform:uppercase;letter-spacing:-.03em;padding:8px 0;min-width:0;font-family:var(--sans)}
.pulse input::placeholder{color:rgba(1,28,26,.8)}
/* .pulse input sets outline:0, which beat the site's own :focus-visible rule. These two put it
   back in a colour that reads on the panel each field actually sits on. */
.pulse input:focus-visible{outline:2px solid var(--ground);outline-offset:4px}
.pulse button{background:var(--ground);color:var(--cream);border:0;border-radius:2px 2px 0 0;padding:0 22px;font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;font-weight:700}
.teal .fine{margin-top:14px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:rgba(1,28,26,.8)}

.close{padding:clamp(90px,15vh,180px) 0}
.close h2{font-size:clamp(2.8rem,7vw,7rem);max-width:12ch}
.close p{margin:26px 0 36px;font-size:1.1rem;max-width:50ch}
/* ---------- THE FOOTER ----------
   Chris, canopy 830: "The footer doesn't feel organised, it feels like an afterthought, so maybe
   we can put some thinking behind how to make this feel great on every page, especially because
   most of the pages are found here as direct links, and not in the header."

   It was one row of ten links in one size and one colour, then a second row starting with a label
   in a different typeface. No grouping, no hierarchy, and no sign of where you are. It is the
   site's table of contents and it looked like a legal line.

   ARCHITECTURE IS RC's: the same four groups as llms.txt, so the map a person gets is the map the
   machines get. Diagnose, Fix & Grow, Proof and answers, Nudge.

   ONE MARKUP, THREE LAYOUTS. Each group is a <details>. On a wide screen CSS forces it open and
   removes the marker, so it is a column; on a phone it is a tappable row. Nothing is duplicated,
   nothing depends on a script, and the group holding the current page carries a static open
   attribute written per page, so a visitor sees where they are without tapping. */
footer{padding:56px 0 140px;border-top:1px solid var(--c10);font-size:13px;color:var(--c60)}
footer a{text-decoration:none;color:var(--c60)}
footer a:hover{color:var(--teal)}
/* Where am I. The footer had no answer to this at all, which is half of why it read as an
   afterthought: ten links, none of them the one you are standing on. */
footer a[aria-current=page]{color:var(--cream)}

footer .ftop{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 18px;margin-bottom:38px}
footer .fmark{font-family:var(--mono);font-size:13px;letter-spacing:.12em;text-transform:uppercase;color:var(--cream)}
footer .fline{margin:0;font-size:13px;color:var(--c60)}

footer .fcols{display:grid;grid-template-columns:repeat(4,1fr);gap:40px}
footer .fgroup>summary{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60);margin-bottom:14px}
footer .fgroup>div{display:flex;flex-direction:column;gap:10px;align-items:flex-start}
footer .fgroup>div a{font-size:14px;color:var(--c80)}
/* A LINK THAT LEAVES THE SITE SAYS SO TO EVERYONE. The three social links already carry an
   accessible name ending "opens in a new tab", so a screen reader is told; a sighted visitor was
   not. god ruled the glyph in. It hangs off [target="_blank"] rather than off a class, because
   that attribute IS the meaning: these are the links that leave, and any future one inherits it.
   ::after rather than markup, so it is decorative. BUT WHAT KEEPS THE GLYPH OUT OF THE
   ACCESSIBLE NAME IS THE aria-label, NOT THE FACT THAT IT IS GENERATED CONTENT. Generated
   content DOES count toward a name built from an element's content; the aria-label simply wins
   over content entirely, so the ::after never gets a chance. Angela proved it rather than
   warning about it, by adding a fourth external link in this group: with a label it was named
   "Nudge on Mastodon, opens in a new tab", and without one the arrow was IN the name. So any
   external link added here needs an aria-label, or it inherits the leak along with the glyph.
   U+2197 is written as an escape and the closing quote terminates it. CSS reads up to six hex
   digits after a backslash, so it must not be followed by one, and a terminating space is
   swallowed. The same trap put U+0091 in this file and made the phone menu read "Menu 2". */
footer .fgroup>div a[target="_blank"]::after{content:"\2197";font-family:var(--mono);font-size:10px;margin-left:5px;vertical-align:2px;color:var(--c60)}
footer .fgroup>div a[target="_blank"]:hover::after{color:var(--teal)}
footer .fgroup>div small{font-size:12px;color:var(--c60);max-width:24ch;line-height:1.5}

footer .fbase{margin-top:44px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60)}

/* WIDE: every group is open and the disclosure marker is gone, so <details> reads as a column.
   The marker needs removing twice - ::marker is the standard, ::-webkit-details-marker is what
   this engine still uses - and missing either leaves a triangle in a column heading. */
@media(min-width:761px){
  footer .fgroup>summary{list-style:none;cursor:default}
  footer .fgroup>summary::-webkit-details-marker{display:none}
  footer .fgroup>summary::marker{content:""}
  /* The content is shown whatever the open attribute says, because open is set per page for the
     phone layout and must not decide what a desktop column shows.
     IT TAKES BOTH OF THESE, and the first screenshot is how I found that out: three of the four
     columns came out EMPTY with only display:flex!important here. A current Chromium no longer
     hides a closed details by putting display:none on the child; it hides the generated
     ::details-content box with content-visibility, which a rule on the child cannot reach. The
     display rule stays for engines that still use the older mechanism. */
  footer .fgroup::details-content{content-visibility:visible;block-size:auto}
  footer .fgroup>div{display:flex!important}
}
@media(min-width:761px) and (max-width:1100px){footer .fcols{grid-template-columns:repeat(2,1fr);gap:36px 40px}}

/* PHONE: the footer menu Chris asked for. Four rows at a 48px tap target, the group holding the
   current page already open. A plus turns into a minus, in CSS alone.
   THE MINUS IS WRITTEN AS A CSS ESCAPE ON PURPOSE. The nav drawer's own open marker is
   content:"\0091 2" on main - an invisible control character and a literal digit - so the phone
   menu reads "Menu 2" when it is open. Something mangled the character on its way into the file.
   An escape cannot be mangled by a re-encoding, so this one says what it means. */
@media(max-width:760px){
  footer{padding-top:40px}
  footer .fcols{display:block;border-top:1px solid var(--c10)}
  footer .fgroup{border-bottom:1px solid var(--c10)}
  footer .fgroup>summary{display:flex;justify-content:space-between;align-items:center;
    min-height:48px;margin:0;cursor:pointer;list-style:none;color:var(--cream)}
  footer .fgroup>summary::-webkit-details-marker{display:none}
  footer .fgroup>summary::marker{content:""}
  footer .fgroup>summary::after{content:"+";font-size:15px;line-height:1;color:var(--c60)}
  footer .fgroup[open]>summary::after{content:"\2212"}
  footer .fgroup[open]>summary{color:var(--teal)}
  /* THE ONE GROUP LABEL THAT IS A LINK TAKES THE ROW IT SITS IN. Lighthouse flags exactly one
     tap target on this page, and it is this anchor: the summary is already 280x48, the anchor
     inside it was 67x18, so two thirds of the height above and below the words did something
     different from the words. The other three labels are plain text, which is why only one is
     flagged and why a rule on summary itself would have been the wrong place.

     align-self:stretch overrides the align-items:center on the summary for this item only, and
     the flex inside it centres the text again. THE WORDS DO NOT MOVE, and the box is the wrong
     thing to measure to prove that, because the box is what deliberately changed: a Range over
     the anchor's own text sits at the same left and top, 67.09x13 in one rect, at 320, 390, 760,
     768 and 1440. Of the 37 boxes in the footer, at five widths, this anchor's height and top are
     the only coordinates that move at all, and they move around the same centre.

     It does change behaviour, deliberately: a tap in the top or bottom 15px over the words now
     follows the link instead of toggling the group. The plus and minus on the right, and the rest
     of the row either side of the words, still toggle it. */
  footer .fgroup>summary>a{align-self:stretch;display:flex;align-items:center}
  footer .fgroup>div{gap:0;padding-bottom:8px}
  footer .fgroup>div a{display:flex;align-items:center;min-height:44px;font-size:15px}
  footer .fgroup>div small{padding:4px 0 10px;max-width:none}
  footer .ftop{margin-bottom:24px}
  footer .fbase{margin-top:32px}
}

/* ---------- hidden until x-ray: the front stays clean ---------- */
[data-doc]{position:relative}

/* ---------- BLUEPRINT TWIN ---------- */
#bp{position:absolute;left:0;top:0;width:100%;z-index:20;pointer-events:none;background:var(--ground);opacity:0;visibility:hidden;
  clip-path:inset(calc(var(--fy) - var(--fh)/2) calc(100% - var(--fx) - var(--fw)/2) calc(100% - var(--fy) - var(--fh)/2) calc(var(--fx) - var(--fw)/2));
  transition:opacity .3s,visibility .3s}
html[data-xray] #bp{opacity:1;visibility:visible}
html[data-xray="full"] #bp{clip-path:inset(0 0 0 0);pointer-events:auto;transition:clip-path .9s var(--ease),opacity .3s}
#bp .grid{position:absolute;inset:0;background-image:linear-gradient(var(--t12) 1px,transparent 1px),linear-gradient(90deg,var(--t12) 1px,transparent 1px);background-size:8px 8px;background-position:0 0}
#bp .grid::after{content:'';position:absolute;inset:0;background-image:linear-gradient(var(--t30) 1px,transparent 1px),linear-gradient(90deg,var(--t30) 1px,transparent 1px);background-size:80px 80px}
#bp .twin{position:relative}
#bp .twin *{color:var(--c40)!important;background:transparent!important;border-color:var(--t30)!important}
#bp .twin h1,#bp .twin h2,#bp .twin h3,#bp .twin .price{color:transparent!important;-webkit-text-stroke:1px var(--t60)}
#bp .twin .btn{color:var(--teal)!important;border:1px dashed var(--t60)!important}
#bp .twin .teal{background:transparent!important;outline:1px solid var(--t60)}
#bp .twin .device{display:none}
#bp .twin .lockup path{fill:none!important;stroke:var(--t60);stroke-width:2}
#bp .twin [data-doc]{outline:1px solid var(--t60);outline-offset:8px;cursor:pointer;pointer-events:auto}
#bp .twin [data-doc]::before{content:attr(data-role) ' · ' attr(data-doc);position:absolute;left:-9px;top:-27px;font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--ground)!important;background:var(--teal)!important;padding:3px 7px;line-height:1.3;font-weight:700;white-space:nowrap;z-index:2}
#bp .twin [data-doc]::after{content:attr(data-dim);position:absolute;right:-9px;bottom:-24px;font-family:var(--mono);font-size:9.5px;letter-spacing:.06em;color:var(--teal)!important;white-space:nowrap}
#bp .twin [data-doc]:hover,#bp .twin [data-doc].hot{outline-color:var(--cream);outline-width:2px}
#bp .twin [data-doc].hot::before{background:var(--cream)!important}
#bp .twin [data-doc].open{outline-color:var(--cream);outline-width:2px;background:var(--t12)!important}
#bp .twin [data-doc] [data-doc]{outline-offset:4px}
#bp .twin [data-doc] [data-doc]::before{top:auto;bottom:100%;margin-bottom:6px;left:auto;right:-5px}
/* dimension rulers on the twin */
#bp .twin .hero::after{content:'';position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--t30)}

/* ---------- THE VIEWFINDER (square) ---------- */
/* THE PHONE BOUNDARY FOR THE WHOLE CONTROL CLUSTER, and it is a WIDTH, on god's instruction.
   This exact query is mirrored once in site.js, which reads it with matchMedia so the script
   and the stylesheet cannot drift apart and disagree about what a phone is. Change one and
   change the other.

   720px is not a new number: it is the boundary that already hides the keyboard legend four
   rules below, and it keeps a portrait tablet (768 to 834) intact.

   NOT pointer:coarse, which is the obvious gate and the wrong one. Angela measured it: a
   touchscreen laptop at 1280 reports pointer:coarse, so a touch-gated rule takes the
   viewfinder off a PC, and "tablet and PC unchanged" is the brief. The site.js constant
   `touch` is exactly that gate, already in scope and already used for the frame width, so it
   is the thing a reader will reach for. It is wrong here. */
#vf{position:fixed;z-index:40;left:var(--fx);top:var(--fy);width:var(--fw);height:var(--fh);transform:translate(-50%,-50%);pointer-events:none;opacity:0;transition:opacity .3s}
@media(max-width:720px){#vf{display:none}}
html[data-xray="frame"] #vf{opacity:1}
html[data-xray="frame"] body{cursor:none}
#vf .edge{position:absolute;inset:0;border:1px solid var(--c40)}
#vf .c{position:absolute;width:20px;height:20px;border:2px solid var(--cream)}
#vf .tl{top:-1px;left:-1px;border-right:0;border-bottom:0}#vf .tr{top:-1px;right:-1px;border-left:0;border-bottom:0}
#vf .bl{bottom:-1px;left:-1px;border-right:0;border-top:0}#vf .br{bottom:-1px;right:-1px;border-left:0;border-top:0}
#vf .ruler{position:absolute;left:0;right:0;top:-1px;height:6px;background:repeating-linear-gradient(90deg,var(--c40) 0 1px,transparent 1px 10px)}
#vf .ruler.b{top:auto;bottom:-1px}
#vf .ruler.l,#vf .ruler.r{top:0;bottom:0;left:-1px;right:auto;width:6px;height:auto;background:repeating-linear-gradient(180deg,var(--c40) 0 1px,transparent 1px 10px)}
#vf .ruler.r{left:auto;right:-1px}
#vf .cross::before,#vf .cross::after{content:'';position:absolute;left:50%;top:50%;background:var(--cream);opacity:.6}
#vf .cross::before{width:14px;height:1px;transform:translate(-50%,-50%)}#vf .cross::after{width:1px;height:14px;transform:translate(-50%,-50%)}
#vf .ro{position:absolute;left:0;top:calc(100% + 12px);background:var(--ground);padding:6px 10px;border:1px solid var(--c10);border-radius:2px;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--cream);white-space:nowrap;line-height:1.7}
#vf .ro b{color:var(--teal);font-weight:500}
#vf .ro .hint{color:var(--c60)}
#vf .rec{position:absolute;right:0;bottom:calc(100% + 12px);font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--c60);display:flex;gap:8px;align-items:center}
#vf .rec::before{content:'';width:7px;height:7px;border-radius:9999px;background:var(--teal);animation:blink 1.6s ease-in-out infinite}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.2}}
@media(prefers-reduced-motion:reduce){#vf .rec::before{animation:none}}
html[data-xray="frame"] #page{opacity:.42;transition:opacity .3s}
html[data-xray="full"] #page{opacity:0;pointer-events:none}
#page{transition:opacity .3s}

/* ---------- controls ---------- */
#ctl{position:fixed;right:20px;bottom:calc(20px + env(safe-area-inset-bottom,0px));z-index:60;display:flex;flex-direction:column;align-items:flex-end;gap:8px}
#ctl .keys{font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--c60);text-align:right;line-height:1.8}
#ctl .keys kbd{color:var(--cream);border:1px solid var(--c20);border-radius:2px;padding:0 5px}
#ctl{pointer-events:none}
#ctl>*{pointer-events:auto}
/* On phones the whole keyboard legend is already hidden, so the key badge on the button is a
   hint to a keyboard that is not there. Dropping it and tightening the padding takes the fixed
   button off the hero call to action underneath it.
   This is the same 720px boundary as the #vf rule above, and the two have to stay the same
   number: the button's own label changes to "Put the page back" with an L badge when the page
   is lifted, so a width that hid the viewfinder but kept the badge would point at a key that
   is not there. */
@media(max-width:720px){#ctl .keys{display:none}#ctl{right:12px;bottom:calc(12px + env(safe-area-inset-bottom,0px))}#ctl .btn{padding:10px 14px;font-size:10px;gap:0}#ctl .btn kbd{display:none}}
/* and the hero keeps its centred content clear of that band at phone widths */
@media(max-width:720px){.hero{padding:6vh 0 20vh}}

/* ---------- THE FILE (dossier drawer) ---------- */
#file{position:fixed;top:0;right:0;bottom:0;width:min(520px,100vw);z-index:80;background:var(--surface);border-left:1px solid var(--c10);transform:translateX(100%);transition:transform .6s var(--ease);display:flex;flex-direction:column;padding-top:env(safe-area-inset-top,0px)}
#file.on{transform:none}
#file .head{padding:22px 26px 0;border-bottom:1px solid var(--c10)}
#file .crumbs{display:flex;justify-content:space-between;align-items:center;gap:12px;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--c60)}
#file .crumbs b{color:var(--teal);font-weight:500}
#file .x{background:none;border:1px solid var(--c20);border-radius:2px;color:var(--cream);font-family:var(--mono);font-size:10px;letter-spacing:.08em;padding:5px 9px;text-transform:uppercase}
#file .x:hover{border-color:var(--teal);color:var(--teal)}
#file .h4{font-weight:900;text-transform:uppercase;letter-spacing:-.02em;color:var(--cream);font-size:1.9rem;line-height:1;margin:18px 0 6px}
#file .meta{font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60);margin-bottom:18px;line-height:1.8}
#file .meta b{color:var(--c80);font-weight:500}
.tabs{display:flex;gap:0;overflow-x:auto;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tabs button{flex:0 0 auto;background:none;border:0;border-bottom:2px solid transparent;padding:10px 14px 12px;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--c60);margin-bottom:-1px}
.tabs button.on{color:var(--cream);border-bottom-color:var(--teal)}
.tabs button:hover{color:var(--teal)}
.tabs button i{font-style:normal;color:var(--teal);margin-right:6px;font-size:9.5px}
#file .body{overflow:auto;padding:26px 26px 120px;flex:1;font-size:.95rem;line-height:1.65}
#file .body .h5{font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--teal);margin:26px 0 8px;font-weight:700}
#file .body .h5:first-child{margin-top:0}
#file .body p{color:var(--c80);margin-bottom:12px}
#file .body p.dim{color:var(--c60)}
#file .body ul{list-style:none}
#file .body li{padding:9px 0;border-bottom:1px solid var(--c05);color:var(--c80)}
#file .body li b{color:var(--cream);font-weight:700}
#file .body li.gap{color:var(--amber)}
#file .body li.gap::before{content:'gap · ';font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase}
#file .opt{padding:12px 14px;border:1px solid var(--c10);border-radius:2px;margin-bottom:8px;color:var(--c60);position:relative}
#file .opt.no{text-decoration:line-through;text-decoration-color:var(--red);text-decoration-thickness:1px}
#file .opt.yes{border-color:var(--teal);color:var(--cream);background:var(--t12)}
#file .opt .why{display:block;font-size:.85rem;color:var(--c60);margin-top:4px;text-decoration:none;font-family:var(--mono);text-transform:uppercase;letter-spacing:.04em;font-size:10px}
#file .opt.yes .why{color:var(--teal)}
/* drafts */
.drafts{border:1px solid var(--c10);border-radius:2px;padding:18px 18px 16px;background:var(--ground)}
.drafts .txt{font-weight:700;color:var(--cream);font-size:1.15rem;line-height:1.35;min-height:5.2em}
.drafts .txt.big{font-weight:900;text-transform:uppercase;letter-spacing:-.03em;font-size:1.6rem;line-height:1.05}
.drafts del{color:var(--red);text-decoration:line-through;text-decoration-thickness:1px;opacity:.85}
.drafts ins{color:var(--teal);text-decoration:none;border-bottom:1px solid var(--teal)}
.drafts .bar{display:flex;align-items:center;gap:14px;margin-top:16px}
.drafts input[type=range]{flex:1;accent-color:var(--teal)}
.drafts .v{font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--c60);min-width:70px}
.drafts .v b{color:var(--cream);font-weight:500}
.drafts .note{margin-top:12px;font-size:.88rem;color:var(--c60);font-style:normal}
.drafts .stats{display:flex;gap:18px;flex-wrap:wrap;margin-top:12px;font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60)}
.drafts .stats b{color:var(--c80);font-weight:500}
/* build */
.kv{display:grid;grid-template-columns:auto 1fr;gap:8px 18px;font-family:var(--mono);font-size:11px;letter-spacing:.04em;color:var(--c60)}
.kv dt{color:var(--c60);text-transform:uppercase;letter-spacing:.08em}
.kv dd{color:var(--c80);word-break:break-word}
.kv dd.ok{color:var(--green)}.kv dd.warn{color:var(--amber)}.kv dd.bad{color:var(--red)}
pre.code{font-family:var(--mono);font-size:11px;line-height:1.55;color:var(--c60);background:var(--ground);border:1px solid var(--c10);border-radius:2px;padding:14px 16px;white-space:pre-wrap;word-break:break-word;margin-top:8px}
pre.code b{color:var(--teal);font-weight:500}
.swatch{display:inline-block;width:11px;height:11px;border-radius:2px;vertical-align:-1px;margin-right:6px;border:1px solid var(--c20)}
/* measure */
.metric{padding:14px 16px;border:1px solid var(--c10);border-radius:2px;margin-bottom:8px}
.metric .k{font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--c60)}
.metric .v{color:var(--cream);font-weight:700;margin-top:3px}
.metric .s{font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;margin-top:6px}
.metric .s.pending{color:var(--amber)}.metric .s.live{color:var(--green)}
/* index */
.idx{list-style:none}
.idx li{display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:center;padding:10px 0;border-bottom:1px solid var(--c05);cursor:pointer}
.idx li:hover{color:var(--teal)}
.idx li .n{font-family:var(--mono);font-size:10px;color:var(--c60);letter-spacing:.06em}
.idx li .r{font-family:var(--mono);font-size:10px;color:var(--teal);letter-spacing:.06em;text-transform:uppercase}
.idx li b{color:var(--c80);font-weight:500;font-size:.92rem}
.idx li.h{cursor:default;grid-template-columns:1fr;padding:22px 0 6px;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--teal);border:0}
.idx li.h:hover{color:var(--teal)}
.idx li.h small{display:block;color:var(--c60);text-transform:none;letter-spacing:0;font-family:var(--sans);font-size:.9rem;margin-top:4px;font-weight:500}
.procmap{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin:14px 0 20px}
.procmap div{background:var(--ground);border:1px solid var(--c10);border-radius:2px;padding:10px 4px;text-align:center;font-family:var(--mono);font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60)}
.procmap div b{display:block;color:var(--cream);font-size:1.3rem;font-weight:900;letter-spacing:-.02em;margin-bottom:2px}

/* ===== motion ===== */

/* ================= MOTION SYSTEM ================= */
/* grain */
#grain{position:fixed;inset:0;z-index:2;pointer-events:none;opacity:.055;mix-blend-mode:overlay;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");background-size:200px 200px}
/* three-row signature device */
.device{position:fixed;left:0;right:0;top:0;height:100vh;overflow:hidden;pointer-events:none;z-index:0;display:flex;flex-direction:column;justify-content:center;gap:0}
.device div{white-space:nowrap;font-weight:900;font-size:22vh;line-height:.82;text-transform:uppercase;letter-spacing:-.04em;color:transparent;-webkit-text-stroke:1px var(--c05);will-change:transform;animation:drift 120s linear infinite}
.device div:nth-child(2){animation-name:driftR;-webkit-text-stroke-color:rgba(28,174,160,.09)}
.device div:nth-child(3){animation-delay:-40s}
@keyframes driftR{from{transform:translateX(-50%)}to{transform:translateX(0)}}
@media(max-width:760px){.device div{font-size:14vh}}
@media(prefers-reduced-motion:reduce){.device div{animation:none}}
/* sticky nav */
.nav{position:sticky;top:0;z-index:30;transition:padding .4s}
.nav::before{content:'';position:absolute;top:0;bottom:0;left:calc(50% - 50vw);right:calc(50% - 50vw);z-index:-1;background:rgba(1,28,26,0);border-bottom:1px solid transparent;transition:background .4s,border-color .4s;backdrop-filter:blur(12px)}
.nav.stuck{padding-top:14px;padding-bottom:14px}
.nav.stuck::before{background:rgba(1,28,26,.82);border-bottom-color:var(--c10)}
.lockup{transition:transform .5s var(--ease)}
.lockup{overflow:visible}
.lockup .mk{transition:transform .5s var(--ease);transform-box:fill-box}
a:hover .lockup .mk{transform:translateX(-6px)}
/* cursor */
#cur{position:fixed;left:0;top:0;width:14px;height:14px;border-radius:9999px;background:var(--cream);pointer-events:none;z-index:200;mix-blend-mode:difference;transform:translate(-50%,-50%);transition:width .25s var(--ease),height .25s var(--ease),border-radius .25s var(--ease),background .25s,border .25s,opacity .3s;will-change:left,top}
#cur.link{width:44px;height:44px;background:transparent;border:1px solid var(--cream)}
#cur.doc{width:28px;height:28px;border-radius:2px;background:transparent;border:0;
  background-image:linear-gradient(var(--cream),var(--cream)),linear-gradient(var(--cream),var(--cream)),linear-gradient(var(--cream),var(--cream)),linear-gradient(var(--cream),var(--cream)),linear-gradient(var(--cream),var(--cream)),linear-gradient(var(--cream),var(--cream)),linear-gradient(var(--cream),var(--cream)),linear-gradient(var(--cream),var(--cream));
  background-repeat:no-repeat;background-size:8px 1px,1px 8px,8px 1px,1px 8px,8px 1px,1px 8px,8px 1px,1px 8px;background-position:0 0,0 0,100% 0,100% 0,0 100%,0 100%,100% 100%,100% 100%}
#cur.onteal{mix-blend-mode:normal;background:var(--ground)}#cur.onteal.link,#cur.onteal.doc{background:transparent;border-color:var(--ground);background-image:none;border:1px solid var(--ground)}
#cur.down{transform:translate(-50%,-50%) scale(.8)}
#cur.hide,html[data-xray="frame"] #cur{opacity:0}
@media(pointer:coarse){#cur{display:none}}
html.fine body{cursor:none}
html.fine a,html.fine button,html.fine input{cursor:none}
/* word rise */
.wd{display:inline-block;vertical-align:bottom;clip-path:inset(-.4em -.25em 0 -.25em)}
.done .wd{clip-path:none}
.wd>span{display:inline-block;transform:translateY(112%);transition:transform .9s var(--ease),color .3s,-webkit-text-stroke .3s;transition-delay:calc(var(--i,0)*45ms)}
.in .wd>span,.hero.in .wd>span{transform:none}
h1 .wd>span:hover,.sec h2 .wd>span:hover,.close h2 .wd>span:hover{color:transparent;-webkit-text-stroke:1px var(--cream)}
.teal h2 .wd>span:hover{-webkit-text-stroke-color:var(--ground)}
h1 .dot,.sec h2 .dot,.close h2 .dot{display:inline-block;}
.js h1 .dot,.js .sec h2 .dot,.js .close h2 .dot{transform:scale(0);transition:transform .5s var(--ease);transition-delay:calc(var(--n,10)*45ms + .5s)}
.hero.in h1 .dot,.sec.in h2 .dot,.close.in h2 .dot{transform:scale(1)}
/* fades */
.js .fd{opacity:0;transform:translateY(14px);transition:opacity .8s var(--ease),transform .8s var(--ease);transition-delay:var(--d,0s)}
.in .fd,.fd.in{opacity:1;transform:none}
/* rule draw on sections */
section.sec{border-top:0;position:relative}
section.sec::before{content:'';position:absolute;left:0;right:0;top:0;height:1px;background:var(--c10);transform-origin:left;}
.js section.sec::before{transform:scaleX(0);transition:transform 1.4s var(--ease)}
section.sec.in::before{transform:scaleX(1)}
section.sec.teal::before{display:none}
/* findings typing */
.pattern .q{min-height:1.4em}
.pattern .q .cr{display:inline-block;width:1px;height:1em;background:var(--teal);vertical-align:-.15em;margin-left:2px;animation:blink 1s steps(2) infinite}
.js .pattern li{opacity:0;transform:translateY(10px);transition:opacity .7s var(--ease),transform .7s var(--ease);transition-delay:calc(var(--i)*140ms)}
.in .pattern li{opacity:1;transform:none}
/* steps */
.js .steps article{opacity:0;transform:translateY(16px);transition:opacity .8s var(--ease),transform .8s var(--ease),background .3s;transition-delay:calc(var(--i)*120ms)}
.in .steps article{opacity:1;transform:none}
.steps article:hover{background:var(--surface)}
.steps article .out{transition:color .3s}
.steps article:hover .out b{color:var(--teal)}
/* rubric run */
.js .rubric tr{opacity:0;transform:translateX(-6px);transition:opacity .5s var(--ease),transform .5s var(--ease)}
.rubric tr.run{opacity:1;transform:none}
.rubric td.res .scan{display:inline-block;letter-spacing:2px;color:var(--c60);animation:scan .6s steps(3) infinite}
@keyframes scan{0%{content:'▮'}}
.rubric .score{transition:color .3s}
/* buttons: fill from the left, magnetic */
.btn{position:relative;overflow:hidden;isolation:isolate;transition:transform .35s var(--ease),color .3s,border-color .3s;will-change:transform}
.btn::after{content:'';position:absolute;inset:0;background:var(--teal);z-index:-1;transform:scaleX(0);transform-origin:left;transition:transform .45s var(--ease)}
.btn:hover{background:var(--cream)}
.btn:hover::after{transform:scaleX(1)}
.btn.ghost:hover{color:var(--ground);border-color:var(--teal)}
/* price */
.price i{font-variant-numeric:tabular-nums}
/* pulse underline draw + typed placeholder */
.pulse{border-bottom:0;position:relative}
.pulse::after{content:'';position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--ground);transform:scaleX(0);transform-origin:left;transition:transform 1.2s var(--ease) .2s}
.in .pulse::after{transform:scaleX(1)}
/* viewfinder entrance */
#vf{transform:translate(-50%,-50%) scale(.92);transition:opacity .35s var(--ease),transform .5s var(--ease)}
html[data-xray="frame"] #vf{transform:translate(-50%,-50%) scale(1)}
#vf .c{transition:transform .5s var(--ease)}
#vf .tl{transform:translate(-10px,-10px)}#vf .tr{transform:translate(10px,-10px)}#vf .bl{transform:translate(-10px,10px)}#vf .br{transform:translate(10px,10px)}
html[data-xray="frame"] #vf .c{transform:none}
/* file drawer: contents stagger */
#file .body>*{opacity:0;transform:translateY(8px);transition:opacity .5s var(--ease),transform .5s var(--ease)}
#file.on .body>*{opacity:1;transform:none}
#file.on .body>*:nth-child(1){transition-delay:.15s}#file.on .body>*:nth-child(2){transition-delay:.2s}#file.on .body>*:nth-child(3){transition-delay:.25s}#file.on .body>*:nth-child(4){transition-delay:.3s}#file.on .body>*:nth-child(5){transition-delay:.35s}#file.on .body>*:nth-child(n+6){transition-delay:.4s}
@media(prefers-reduced-motion:reduce){
  .rubric td.res .scan{animation:none}
  .wd>span,.fd,.pattern li,.steps article,.rubric tr,section.sec::before,.pulse::after,h1 .dot,.sec h2 .dot,.close h2 .dot,#score h2 #rdom::after{transition:none!important;transform:none!important;opacity:1!important}
  .btn::after{transition:none}
  #cur{display:none} html.fine body{cursor:auto}
}


/* ===== signal audit / shared components ===== */

/* signal audit page */
.pattern .n{min-width:34px}
.tenq{display:grid;grid-template-columns:1.25fr .75fr;gap:2px;background:var(--c10);border:1px solid var(--c10);border-radius:2px;margin-top:40px}
@media(max-width:900px){.tenq{grid-template-columns:1fr}}
.qs{background:var(--ground)}
.q{padding:24px 28px;border-bottom:1px solid var(--c05);display:grid;grid-template-columns:44px 1fr;gap:16px;align-items:start;transition:background .3s}
.q:last-child{border-bottom:0}
.q.done{background:var(--surface)}
.q .n{font-family:var(--mono);font-size:11px;color:var(--teal);letter-spacing:.08em;padding-top:5px}
.q p{color:var(--cream);font-weight:700;font-size:1.08rem;line-height:1.4;margin-bottom:12px}
.q .opts{display:flex;flex-wrap:wrap;gap:8px}
.q .opts button{background:transparent;border:1px solid var(--c20);border-radius:2px;padding:8px 14px;font-size:.92rem;color:var(--c80);transition:border-color .3s,background .3s,color .3s}
.q .opts button:hover{border-color:var(--teal);color:var(--cream)}
.q .opts button.on{background:var(--cream);color:var(--ground);border-color:var(--cream)}
.qr{background:var(--surface)}
.qr .in2{position:sticky;top:90px;padding:28px}
.bar{margin-bottom:18px}
.bar .lbl{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px;font-size:.95rem}
.bar .lbl b{color:var(--cream);font-weight:700}
.bar .lbl span{font-family:var(--mono);font-size:11px;color:var(--c60)}
.bar .trk{height:4px;background:var(--c10);border-radius:2px;overflow:hidden}
.bar .trk i{display:block;height:100%;width:0;background:var(--teal);transition:width .8s var(--ease)}
.bar.lead .trk i{background:var(--cream)}
.verdict{margin-top:22px;color:var(--c80);font-size:1rem;line-height:1.6;min-height:4.8em}
.verdict b{color:var(--cream)}
.timeline{list-style:none;margin-top:40px;border-top:1px solid var(--c10);max-width:900px}
.timeline li{display:grid;grid-template-columns:110px 1fr;gap:24px;padding:22px 0;border-bottom:1px solid var(--c10);font-size:1.02rem;transition:opacity .7s var(--ease),transform .7s var(--ease);transition-delay:calc(var(--i)*110ms)}
.js .timeline li{opacity:0;transform:translateY(10px)}
.in .timeline li{opacity:1;transform:none}
.timeline .t{font-family:var(--mono);font-size:11px;letter-spacing:.08em;color:var(--teal);padding-top:5px;text-transform:uppercase}
.timeline b{color:var(--cream);font-weight:700}
@media(max-width:600px){.timeline li{grid-template-columns:1fr;gap:6px}}
.docshape{border:1px solid var(--c10);border-radius:2px;background:var(--surface);padding:26px 28px 14px}
.docshape .dh{display:flex;justify-content:space-between;padding-bottom:14px;border-bottom:1px solid var(--c10);margin-bottom:6px}
.docshape ol{list-style:none;counter-reset:d}
.docshape li{counter-increment:d;display:grid;grid-template-columns:28px 1fr;gap:14px;padding:14px 0;border-bottom:1px solid var(--c05)}
.docshape li:last-child{border-bottom:0}
.docshape li::before{content:counter(d,decimal-leading-zero);font-family:var(--mono);font-size:11px;color:var(--teal);padding-top:4px;letter-spacing:.08em}
.docshape b{display:block;color:var(--cream);font-weight:700}
.docshape li span{grid-column:2}
.docshape span{color:var(--c60);font-size:.95rem}


/* ===== pulse ===== */

/* The address the visitor gave is written into #rdom and .rdom by pulse.js, so it is text from
   outside and can be any length. A domain has no break the browser will take by default, so the
   heading would not shrink below the whole string: 316px inside a 280px column at 320, which
   dragged the page 16px. Same answer the file already gives foreign text in four other places. */
#rdom,.rdom{word-break:break-word}
/* TEXT FROM OUTSIDE, IN THE THREE PLACES THE AUDIT FOUND IT. Same house rule as #rdom, .pstat,
   .kv dd, pre.code, .cmppane .pt and .chk .why: the element that holds text the site does not
   choose is told it may break.

   The status line is scoped rather than fixed on .mono itself, because .mono is a site-wide
   class on labels, the nav and the footer, and this is the only .mono on the site that carries
   a word somebody else chose. The quoted sentence and the chips are already scoped by .tool.

   MEASURED BEFORE IT WAS WRITTEN, which god asked for on the chip because it is a flex item and
   a flex item can refuse to shrink below its content. It did not need a flex rule:
     nothing            300: 164px  320: 143px  390: 73px
     min-width:0 only   300: 150px  320: 130px  390: 60px   <- buys 14px, not the fix
     word-break only    300:   0px  320:   0px  390:  0px   <- the rule that does the work
   So one rule, the same one, in all three places. min-width:0 is a partial palliative here in
   exactly the way .grid2>*{min-width:0} was on the Pulse result, and it is left out for the
   same reason: it buys a number, not the fix. */
#machines .side p.mono{word-break:break-word}

/* THE FULL STOP AFTER THE ADDRESS BELONGS TO THE ADDRESS, and it was starting its own line.
   THE MECHANISM, because the symptom points the wrong way. The heading is split into one
   <span class="wd"> per word for the reveal, and every one of those is an inline-block. The
   address lands inside the LAST of them, so that word is an atomic box whose width is the
   WIDEST of its wrapped lines, not the width of its last line. The dot is a separate
   inline-block after it, so the browser places it past that full width and there is nothing
   left on the line. That is why it happened at every width and with short addresses too, not
   only at 320 with a long one: it is not a near miss on space.

   So the dot moves INSIDE the address, where the last line grows to hold it by construction.
   Measured across 12 widths from 300 to 1440 and four addresses, 48 of 48: as it shipped, 36
   of those 48 put the dot on its own line.

   It keeps the scale-in it had, copied from the rule above rather than reinvented, which is
   why it is inline-block: a transform does not apply to a plain inline box. The
   reduced-motion block names it too, because a scale(0) that is never released is an
   invisible full stop. */
#score h2 .dot{display:none}
#score h2 #rdom::after{content:".";color:var(--teal);display:inline-block}
.js #score h2 #rdom::after{transform:scale(0);transition:transform .5s var(--ease);transition-delay:calc(var(--n,10)*45ms + .5s)}
#score.in h2 #rdom::after{transform:scale(1)}

/* The result heading carries the address the visitor gave, so it is the one heading on the site
   whose length is not ours to choose. At the full display size a typical domain took four line
   boxes at 320 and broke mid-word, ending "OLIVE.VERCEL.A / PP". This is the clamp .cmphead
   .cmpscore b already uses, not a new size: it is the LARGEST of the clamps already in this file
   that gets a typical address onto two line boxes, so it gives up the least of the display scale.
   Measured at 320 with nudge-rebuild-olive.vercel.app, 30 characters: 35px took 4 boxes, 29px
   takes 2, and 24px and 21px also take 2, so going smaller buys nothing.
   The break rule above stays as the fallback for an address long enough to need it. */
@media(max-width:479px){#score h2{font-size:clamp(1.8rem,3.4vw,2.6rem)}}

.pulseform{max-width:820px}
.pulseform input:focus-visible{outline:2px solid var(--teal);outline-offset:4px}
.pulseform input{color:var(--cream)}.pulseform input::placeholder{color:var(--c50)}
.pulseform button{background:var(--cream);color:var(--ground)}
.pulseform::after{background:var(--c40)}
.hero.in .pulseform::after{transform:scaleX(1)}
.linkbtn{background:none;border:0;padding:0;font:inherit;color:var(--teal);text-decoration:underline;text-underline-offset:4px;letter-spacing:inherit;text-transform:inherit}
.linkbtn:hover{color:var(--cream)}
/* THE STATUS LOG PRINTS THE ADDRESS THE VISITOR GAVE, so it is text from outside and one line of
   it is a whole URL with no break a browser takes by default. .hero is a single-column grid and
   this is one of its items, so the column could not be narrower than this line: 653px at a 320px
   viewport. Every other item in the hero then stretched to that column, which is why the ADDRESS
   FIELD looked like the cause. It was a symptom; it went back to 194px the moment this line could
   break. Same answer the file gives foreign text at lines 113, 399, 401, 595 and in the pulse
   section. Setting the field value by script never reproduced it, because no status line is
   written until a run. */
.pstat{margin-top:26px;font-family:var(--mono);font-size:12px;line-height:1.9;color:var(--c60);max-width:820px;min-height:0;word-break:break-word}
.pstat .ln{opacity:0;transform:translateY(4px);transition:opacity .35s,transform .35s}.pstat .ln.in{opacity:1;transform:none}
.pstat .ok{color:var(--green)}.pstat .bad{color:var(--red)}.pstat .dim{color:var(--c60)}
.pstat .note{color:var(--amber)}
.scorecard{border:1px solid var(--c10);border-radius:2px;background:var(--surface);padding:26px 28px}
.scorecard .big{font-weight:900;font-size:clamp(3rem,7vw,5.6rem);color:var(--cream);line-height:1;letter-spacing:-.04em;margin:8px 0}
.scorecard .big i{font-style:normal;color:var(--teal)}
.checks{margin-top:40px;border:1px solid var(--c10);border-radius:2px;background:var(--surface)}
.chk{border-bottom:1px solid var(--c05)}
.chk:last-child{border-bottom:0}
.chk button{width:100%;text-align:left;background:none;border:0;padding:16px 26px;display:grid;grid-template-columns:12px 1fr auto;gap:18px;align-items:center;color:var(--c80);font-size:1rem}
.chk button:hover{background:var(--c05)}
.chk .led{width:10px;height:10px;border-radius:9999px}
.chk.ok .led{background:var(--green)}.chk.warn .led{background:var(--amber)}.chk.bad .led{background:var(--red)}
.chk .r{font-family:var(--mono);font-size:11.5px;white-space:nowrap}
.chk.ok .r{color:var(--green)}.chk.warn .r{color:var(--amber)}.chk.bad .r{color:var(--red)}
.chk .why{display:none;padding:0 26px 18px 56px;font-family:var(--mono);font-size:11.5px;line-height:1.7;color:var(--c60);word-break:break-word}
.chk.open .why{display:block}
.chk .why b{color:var(--teal);font-weight:500}
.chk .k{font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60);margin-right:10px}
.chk .cmp{font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60);margin-top:4px}
.chk .cmp b{font-weight:500;color:var(--green)}
@media(max-width:600px){.chk button{grid-template-columns:12px 1fr;padding:14px 18px}.chk .r{grid-column:2}.chk .why{padding-left:18px}}
.saybox{margin-top:22px;background:var(--surface);border:1px solid var(--c10);border-radius:2px;padding:26px 30px;max-width:900px}
.saybox small{display:block;margin-bottom:12px;color:var(--teal)}
.saybox p{color:var(--cream);font-size:1.15rem;line-height:1.6}
.pattern.inl b{display:inline}
.cmp2{margin-top:40px;border:1px solid var(--c10);border-radius:2px;background:var(--surface);overflow:hidden}
.cmph,.cmpr{display:grid;grid-template-columns:1.1fr 1fr 1.3fr;gap:0}
.cmph>span,.cmpr>span{padding:16px 22px;border-bottom:1px solid var(--c05);border-left:1px solid var(--c05)}
.cmph>span:first-child,.cmpr>span:first-child{border-left:0;font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60);padding-top:19px}
.cmph>span{font-weight:900;text-transform:uppercase;letter-spacing:-.02em;color:var(--cream);font-size:1.3rem;line-height:1;padding-top:22px;padding-bottom:18px;border-bottom-color:var(--c10)}
.cmph>span small{display:block;font-family:var(--mono);font-weight:500;font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--teal);margin-top:8px}
.cmpr>span:nth-child(2){color:var(--c60)}.cmpr>span:nth-child(3){color:var(--cream)}
.cmpr:last-child>span{border-bottom:0}
.cmpr>span:nth-child(3)::before{content:'';display:inline-block;width:6px;height:6px;border-radius:9999px;background:var(--teal);margin-right:10px;vertical-align:2px}
@media(max-width:760px){.cmph,.cmpr{grid-template-columns:1fr}.cmph>span:first-child,.cmpr>span:first-child{padding-bottom:4px;border-bottom:0}.cmph>span,.cmpr>span{border-left:0}.cmpr>span:nth-child(2)::before{content:'Pulse · ';font-family:var(--mono);font-size:10px;text-transform:uppercase;color:var(--c60)}.cmpr>span:nth-child(3)::before{content:'Audit · ';width:auto;height:auto;background:none;font-family:var(--mono);font-size:10px;text-transform:uppercase;color:var(--teal);border-radius:0}}


/* ---------- pages added 30 Sep: rubric list notes, redacted diagnosis ---------- */
.rub-ok,.rub-bad{display:block;margin-top:6px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--c60);line-height:1.6}
.redact{background:var(--c80);color:transparent;border-radius:2px;padding:0 8px;user-select:none}
.redacted li span[data-fill]{color:var(--c80)}

.redacted .open-item{display:block;margin-top:8px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--amber)}

/* ---------- compare (pulse): two sites, sixteen rows ---------- */
.cmp2 .cres{font-family:var(--mono);font-size:12px;letter-spacing:.04em}.cmp2 .cres.ok{color:var(--green)}.cmp2 .cres.warn{color:var(--amber)}.cmp2 .cres.bad{color:var(--red)}.cmp2 .cres small{display:inline-block;margin-left:10px;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--teal)}
/* ---------- contact form ---------- */
/* Reusable: any form.cform gets this, so a second one elsewhere needs markup and nothing else.
   Radii stay at 2px, no shadows, and every colour is a token, per the brand rules. */
.cform{margin-top:40px;max-width:620px;display:flex;flex-direction:column;gap:22px}
.cform .crow{display:flex;flex-direction:column;gap:8px}
.cform label{font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--c60)}
.cform label .opt{color:var(--c60);text-transform:none;letter-spacing:.04em}
.cform input,.cform select,.cform textarea{background:var(--surface);border:1px solid var(--c20);border-radius:2px;padding:13px 14px;color:var(--cream);font-family:var(--sans);font-weight:500;font-size:1rem;line-height:1.5;width:100%}
.cform textarea{resize:vertical;min-height:140px}
.cform input::placeholder,.cform textarea::placeholder{color:var(--c40)}
.cform input:hover,.cform select:hover,.cform textarea:hover{border-color:var(--c40)}
.cform input:focus-visible,.cform select:focus-visible,.cform textarea:focus-visible{outline:2px solid var(--teal);outline-offset:2px;border-color:var(--teal)}
.cform button[type=submit]{align-self:flex-start}
.cform button[disabled]{opacity:.6}
/* The honeypot. Off screen rather than display:none, because some bots skip what is not rendered. */
.cform .hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.cstat{margin-top:18px;font-family:var(--mono);font-size:12px;letter-spacing:.04em;line-height:1.7;max-width:620px}
.cstat:empty{display:none}
.cstat.working{color:var(--c60)}
.cstat.ok{color:var(--green)}
.cstat.bad{color:var(--red)}
p.cfallback{margin-top:26px;max-width:620px;font-size:.95rem;color:var(--c60);border-top:1px solid var(--c10);padding-top:20px}
/* :not(.btn) because this card is RC's .pricebox, and a button in it already has its own
   colour pair - cream fill with ground text, 15.11:1. Painting it teal took it to 2.35:1. */
.cfallback a:not(.btn){color:var(--teal);text-decoration:underline;text-underline-offset:4px}
/* Lit when the endpoint could not send, so the route that still works is the thing being read. */
.cfallback.lit{border-color:var(--teal)}
p.cfallback.lit{color:var(--c80);border-top-color:var(--teal)}
@media(max-width:600px){.cform button[type=submit]{align-self:stretch;justify-content:center}}
