/* stevenjovanovich.me. One stylesheet: type, spacing, motion and assets. */
@font-face{font-family:"SJ Sans";src:url("fonts/SourceSans3-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"SJ Sans";src:url("fonts/SourceSans3-600.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"SJ Serif";src:url("fonts/GeistSerif-Latin.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
/* Metric fallbacks, so text keeps its line breaks while the web fonts load.
   Serif values come from the Geist Serif, Liberation Serif (Times metrics), DejaVu Serif and Georgia (Capsize) tables. */
@font-face{font-family:"SJ Sans Fallback";src:local("Arial"),local("ArialMT"),local("Liberation Sans"),local("Roboto");size-adjust:92.3%;ascent-override:108.3%;descent-override:35.3%;line-gap-override:0%}
@font-face{font-family:"SJ Serif FB Georgia";src:local("Georgia");size-adjust:103.8%;ascent-override:96.8%;descent-override:28.4%;line-gap-override:0%}
@font-face{font-family:"SJ Serif FB Times";src:local("Times New Roman"),local("TimesNewRomanPSMT"),local("Liberation Serif");size-adjust:113.9%;ascent-override:88.2%;descent-override:25.9%;line-gap-override:0%}
@font-face{font-family:"SJ Serif FB DejaVu";src:local("DejaVu Serif");size-adjust:90.4%;ascent-override:111.2%;descent-override:32.7%;line-gap-override:0%}
:root{
  --paper:#fbfaf6;--mist:#eef1f4;--ink:#0a1f3d;--blue:#0b63bd;--amber:#9a5800;--amber-night:#f0a94a;--alert:#b42318;
  --night:#081633;--on-night:#eaf3ff;--ink-soft:#3a4b62;--night-soft:#bdc7d6;
  --rule:#0a1f3d1f;--rule-night:#eaf3ff2e;
  --f-sans:"SJ Sans","SJ Sans Fallback",Arial,sans-serif;
  --f-serif:"SJ Serif","SJ Serif FB Georgia","SJ Serif FB Times","SJ Serif FB DejaVu",Georgia,serif;
  /* spacing: 4 8 12 16 24 32 48 64 96 128 */
  --s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:24px;--s6:32px;--s7:48px;--s8:64px;
  --section:clamp(64px,4rem + 4vw,128px);
  /* type: 13 14 15 17 18 20 28, then fluid tile, H2 and display. Serif only at 24px and up. */
  --t-label:.8125rem;--t-sm:.875rem;--t-base:1.125rem;--t-h3:1.25rem;--t-h3d:1.75rem;
  --h2:clamp(2rem,1.4rem + 2.2vw,3.25rem);
  /* motion */
  --d-fast:100ms;--d-base:160ms;--d-slow:240ms;--ease-out:cubic-bezier(.2,.8,.2,1);
  /* one light source, navy-tinted layered shadows */
  --shadow-color:216deg 70% 6%;
  --shadow-card:0 1px 1px hsl(var(--shadow-color)/.06),0 4px 8px -2px hsl(var(--shadow-color)/.07),0 14px 28px -12px hsl(var(--shadow-color)/.14);
  --radius-panel:6px;
  
  --pad:clamp(20px,4vw,48px);--wrap:1200px;--header-h:64px;
  color-scheme:light;color-scheme:only light;
}
@media (prefers-contrast:more){:root{--blue:#07478a;--amber:#6f3f00;--alert:#8a1a12}}
*,*::before,*::after{box-sizing:border-box}
html{background:var(--night);scroll-padding-top:calc(var(--header-h) + var(--s4));scroll-padding-bottom:var(--s4);-webkit-text-size-adjust:100%;text-size-adjust:100%}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
body{margin:0;background:var(--paper);color:var(--ink);font:400 var(--t-base)/1.55 var(--f-sans);text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased}
@media (max-width:760.98px){body{font-size:1.0625rem}}
b{font-weight:600}
h1,h2,h3,h4,p,ul,ol,figure,blockquote{margin:0}
ul,ol{padding:0;list-style:none}
img{max-width:100%;height:auto;display:block}
a{color:inherit}
button{font:inherit;color:inherit}
a,button{-webkit-tap-highlight-color:transparent;touch-action:manipulation}
button,.button{-webkit-user-select:none;user-select:none}
p,li,figcaption{text-wrap:pretty}
h1,h2{font-family:var(--f-serif);font-weight:400;text-transform:none;letter-spacing:-.015em;text-wrap:balance;font-kerning:normal}
h2{font-size:var(--h2);line-height:1.08}
h3{font:600 var(--t-h3)/1.3 var(--f-sans);text-wrap:balance}
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
:focus-visible{outline:3px solid var(--blue);outline-offset:3px;border-radius:2px}
.wrap{width:min(100% - 2 * var(--pad),var(--wrap));margin-inline:auto}
.lead{max-width:62ch;color:var(--ink-soft)}
.sprite{position:absolute;width:0;height:0;overflow:hidden}
.i{display:inline-block;flex:none;width:1em;height:1em;vertical-align:-.125em;overflow:visible}
.i-ext{width:.8em;height:.8em;margin-left:.2em;vertical-align:-.05em}
/* One caps role: short single-line labels and stamps */
.stamp,.rule-label{font-family:var(--f-sans);font-weight:600;font-size:var(--t-label);text-transform:uppercase;letter-spacing:.12em}

/* Skip link and header */
.skip-link{position:fixed;left:var(--s3);top:-120px;z-index:50;padding:var(--s3) var(--s4);background:var(--paper);color:var(--ink);font-weight:600;border-radius:4px;box-shadow:var(--shadow-card)}
.skip-link:focus{top:var(--s3)}
.skip-link:focus-visible{outline-color:var(--paper)}
.site-header{position:fixed;inset:0 0 auto;z-index:30;height:var(--header-h);background:var(--night);color:var(--paper)}
.header-row{height:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--s5)}
/* Short landscape screens: the header stays fixed (switching it to absolute made phones jump to the top on rotation) but slimmer. */
@media (max-height:480px){:root{--header-h:52px}}
.brand{font:600 1.0625rem/1 var(--f-sans);letter-spacing:.01em;text-decoration:none;min-height:44px;display:inline-flex;align-items:center}
@media (min-width:761px){.header-row{width:calc(min(100% - 2 * var(--pad),var(--wrap)) + 2 * var(--s3))}.brand{margin-left:var(--s3)}}

.site-header :focus-visible{outline-color:var(--paper)}

@media (max-width:760.98px){
  .header-row{gap:var(--s2)}

  .brand{font-size:min(1.0625rem,5.4vw)}
}

/* Cover: type on the night */
.cover{display:grid;grid-template-areas:"stack";position:relative;background:var(--night)}
.cover>*{grid-area:stack}

.docket{position:relative;z-index:4;align-self:end;justify-self:start;width:min(700px,100% - 2 * var(--pad));margin:calc(var(--header-h) + var(--s7)) 0 var(--s8) max(var(--pad),(100% - var(--wrap)) / 2);padding:var(--s6) var(--s7);background:var(--paper);color:var(--ink)}
/* Panels (hero, contact and 404 dockets): a clean paper card with a hairline edge, a thin navy cap and a layered shadow. */
.docket-body{margin-top:var(--s4);max-width:62ch;font-size:1.1875rem;color:var(--ink-soft)}
.docket-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3);margin-top:var(--s5)}
/* Touch: keep 44px between stacked source ticks so their hit areas do not overlap. */

@media (max-width:760.98px){
  .cover{grid-template-areas:"stage" "docket"}

  .docket{grid-area:docket;width:auto;margin:-48px var(--s3) var(--s6);padding:var(--s5)}
}

/* Buttons and links */
.button{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding:0 var(--s5);border:1px solid transparent;border-radius:6px;background:var(--blue);color:#fff;font:600 1rem/1.55 var(--f-sans);text-decoration:none;cursor:pointer}
.button-ink{background:var(--ink)}

.text-link{display:inline-flex;align-items:center;min-height:44px;font-weight:600;color:var(--blue);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px}

.text-button{min-height:44px;padding:0 var(--s1);background:none;border:0;color:var(--blue);font-weight:600;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px;cursor:pointer}
@media (prefers-reduced-motion:no-preference){.button:active{transform:scale(.98)}}

/* Sections */
.section{padding-block:var(--section)}
.section h2+p,.section h2+.lead{margin-top:var(--s5)}

/* Try it: the job sheet */


.step{display:grid;grid-template-columns:2.6rem minmax(0,1.8fr) 8.5rem;gap:var(--s4);align-items:center;min-height:72px;padding:var(--s3) 0;border-bottom:1px solid var(--rule)}
.step-text{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.8fr);gap:var(--s1) var(--s4);align-items:baseline}
@media (min-width:761px){.step-text{align-items:center}}
.step-do{font-weight:600}
.step-rule{font:400 .9375rem/1.45 var(--f-sans);color:var(--ink-soft)}
.step-note{display:block;color:var(--alert);font-weight:600}
.stamp{display:inline-block;padding:6px 10px 5px;border:2px solid currentColor;border-radius:4px;line-height:1;transform:rotate(-2deg)}
.stamp-checked{color:var(--ink-soft)}
.stamp-stopped{color:var(--alert);transform:rotate(2deg)}
.step[data-result="stopped"]:not(.is-pending){background:linear-gradient(90deg,#b4231810,#b4231800 70%)}
.sheet-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) var(--s5);margin-top:var(--s4)}

.sheet:focus-visible{outline:3px solid var(--blue);outline-offset:4px}
/* JS states */
.step.is-pending .step-do,.step.is-pending .step-n{opacity:.8}.step.is-pending .step-rule{opacity:0}
.step.is-pending .stamp{opacity:0}
@media (prefers-reduced-motion:no-preference){
  .step-do,.step-n,.step-rule{transition:opacity var(--d-slow) var(--ease-out)}
  .step.is-stamped .step-note{animation:type var(--d-slow) var(--ease-out) both}
  .step.is-stamped .stamp{animation:stamp 120ms var(--ease-out) both}
  .step.is-stamped .stamp-stopped{animation:stamp-stop 120ms var(--ease-out) both,shake 200ms 120ms linear}
  
  @keyframes type{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
  @keyframes stamp{from{opacity:0;transform:scale(1.15) rotate(-4deg)}to{opacity:1;transform:rotate(-2deg)}}
  @keyframes stamp-stop{from{opacity:0;transform:scale(1.15) rotate(4deg)}to{opacity:1;transform:rotate(2deg)}}
  @keyframes shake{0%,100%{translate:0}25%{translate:-3px}75%{translate:3px}}
}
.running .step:not(.is-stamped) .stamp{opacity:0}
.running .step:not(.is-stamped) .step-note{opacity:0}
.running .sheet-end{opacity:0}
@media (max-width:760.98px){
  .step-text{grid-template-columns:1fr}
  .rule-label{margin-right:var(--s1)}
  
  
  .sheet-actions .text-button{padding-inline:0}
}

/* Reviews: open quotes on the page, a hairline between them */
.reviews{background:var(--mist)}

.quotes{display:grid}
.quote blockquote p{font:400 1.1875rem/1.55 var(--f-sans);color:var(--ink);max-width:60ch;text-indent:-.426em;text-wrap:balance}
.quote figcaption{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s1) var(--s3);margin-top:var(--s4);font-size:.9375rem;color:var(--ink-soft)}
.quote figcaption b{color:var(--ink)}
.stars{display:inline-flex;gap:2px;color:var(--amber)}
.stars .i{width:14px;height:14px}

/* Contact: the closing docket, a pair with the hero */

.contact{background:var(--night)}
.contact{display:grid;align-content:center;scroll-margin-top:calc(-1 * var(--s4))}

.contact-docket{position:relative;padding:var(--s6) var(--s7) var(--s7);background:var(--paper);color:var(--ink)}
.contact-mail{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--s2) var(--s5);margin-top:var(--s6)}
.mail-link{display:inline-flex;align-items:center;min-height:44px;font:400 clamp(1.75rem,1rem + 2.2vw,2.6rem)/1.15 var(--f-serif);letter-spacing:-.01em;color:var(--ink);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:8px;white-space:nowrap}
.copy-email{padding-inline:0}

@media (max-width:760.98px){
}
/* Under 600px the address can't sit on one line at 28px, and serif stays at 28px and up, so it switches to the sans. */
@media (max-width:599.98px){.mail-link{font:600 clamp(1.125rem,6.2vw,1.625rem)/1.2 var(--f-sans);letter-spacing:0}}

/* Without the card (his call, G16): hero and contact type sit straight on the night. Later layers refine these rules. */
/* Hero on the art, 1280 and up */
@media (min-width:1280px){
  .docket{background:none;border:0;box-shadow:none;border-radius:0;padding:0;color:var(--on-night);
    width:min(680px,100% - 2 * var(--pad));align-self:center;
    margin:calc(var(--header-h) + var(--s5)) 0 var(--s7) max(var(--pad),(100% - var(--wrap)) / 2)}

  
}
/* Under 1280: art band, then paper */
@media (min-width:761px) and (max-width:1279.98px){
  .cover{grid-template-areas:"stage" "docket";background:var(--paper)}
  
  .docket{grid-area:docket;width:min(100% - 2 * var(--pad),760px);margin:0 0 0 max(var(--pad),(100% - var(--wrap)) / 2);
    padding:var(--s6) 0 var(--s7);border:0;border-radius:0;box-shadow:none;background:none;align-self:start}
}
/* A tablet on its side: a shorter art band, so the proof lines stay on the first screen */
@media (min-width:761px) and (max-width:1279.98px) and (max-height:860px){
}
/* Section headings step down on phones, so the headline leads. */
@media (max-width:760.98px){
  
}
/* Short screens, such as a phone on its side */

/* Contact: night surface */

.contact-docket{background:none;border:0;box-shadow:none;border-radius:0;padding:0;color:var(--on-night)}
.contact-docket h2{color:var(--on-night)}
.contact-docket .lead{color:var(--night-soft)}
.contact-docket .mail-link{color:#fff;overflow-wrap:anywhere;min-width:0;max-width:100%;white-space:normal}

.contact-docket :focus-visible{outline-color:var(--on-night)}


@media (max-width:760.98px){.contact-docket{padding:0}}
@media (min-width:901px){
  .contact-docket>*{grid-column:2}
  .contact-docket>h2{grid-column:1;grid-row:1/20}
}
@media print{.docket,.docket *,.contact-docket,.contact-docket *{color:var(--ink)!important}}
/* End without the card */

@media (max-width:760.98px){
  .sheet{padding-inline:var(--s5)}
}
/* Footer */
.footer{background:var(--night);color:var(--night-soft);border-top:1px solid var(--rule-night);font-size:var(--t-sm)}
.footer-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--s2) var(--s5);padding-block:var(--s4)}
.footer-end{display:flex;align-items:center;gap:var(--s5);margin-left:auto}
.footer a{min-height:44px;display:inline-flex;align-items:center;font-weight:600;color:var(--paper);text-decoration-thickness:1px;text-underline-offset:5px}
.footer :focus-visible{outline-color:var(--paper)}
#main:focus,#contact-title:focus{outline:none}

/* Hover only where there is a real pointer, so nothing sticks after a tap */
@media (hover:hover) and (pointer:fine){
  .button-ink:hover{background:#13305a}
  
  .text-link:hover{text-decoration-thickness:2px}
  .text-button:hover{text-decoration-thickness:2px}
}

/* Redesign (2026-11-05): a poster, a proof and a close. Flat bands, big type, no menu.
   These rules sit after the older ones on purpose and win over them. */
:root{
  --display:clamp(1.75rem,9.2vw,4.5rem);--h2:clamp(2.25rem,1.3rem + 3vw,4rem);
  --tile:clamp(1.75rem,1.2rem + 1.5vw,2.5rem);--num:clamp(2.25rem,1.6rem + 1.6vw,3.25rem);
  --section:clamp(56px,3rem + 3vw,96px);
}
/* Phones: section headings and proof numbers always sit below the page headline (9.2vw) */
@media (max-width:599.98px){:root{--h2:clamp(1.625rem,7.6vw,1.875rem);--num:clamp(1.5rem,7vw,2.25rem);--tile:1.5rem}}
/* Header: the name and one link, at every width */
.header-employers{min-height:44px;display:inline-flex;align-items:center;font-weight:600;font-size:min(.9375rem,4.4vw);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px;white-space:nowrap;position:relative;top:1px}
@media (min-width:761px){.header-employers{margin-right:var(--s3)}}
/* Hero: white type on the night, at every width */
.docket{background:none;border:0;border-radius:0;box-shadow:none;color:var(--on-night)}
.docket h1{margin-top:0;color:#fff;font-size:var(--display);line-height:1.02;letter-spacing:-.025em}
.docket .docket-body{margin-top:var(--s5);font-size:1.25rem;color:var(--on-night);text-wrap:balance}
.docket .docket-actions{margin-top:var(--s6)}
.docket .button{min-height:56px;padding:0 var(--s6);background:var(--paper);color:var(--ink);font-size:1.0625rem}

.docket :focus-visible{outline-color:#fff}
.docket .docket-facts{display:flex;flex-wrap:wrap;gap:var(--s5) var(--s7);margin-top:var(--s7);padding-top:0;border-top:0;font-size:.9375rem;color:var(--on-night)}
.docket-facts li{display:grid;gap:var(--s1);align-content:start;justify-items:start}
.docket-facts li span{max-width:24ch;text-wrap:balance}
.docket-facts .num{font:400 var(--num)/1 var(--f-serif);letter-spacing:-.02em;color:#fff;white-space:nowrap;font-variant-numeric:lining-nums}
@media (hover:hover) and (pointer:fine){.docket .button:hover{background:#dce8f6}.header-employers:hover{text-decoration-thickness:2px}}
@media (min-width:1280px){
}
@media (max-width:1279.98px){
  .cover{background:var(--night)}

}
@media (max-width:760.98px){
  .cover{background:var(--night)}
  
  .docket h1{font-size:var(--display)}
  .docket .docket-body{font-size:1.125rem;margin-top:var(--s4)}
  .docket .docket-actions{margin-top:var(--s5)}
  .docket .docket-facts{gap:var(--s5) var(--s6);margin-top:var(--s6)}
}
/* Cover without a picture (2026-11-05): type on the night, the proof beside it on wide screens */
.cover{display:block;background:var(--night)}
.docket{display:grid;width:min(100% - 2 * var(--pad),var(--wrap));margin:0 auto;padding:calc(var(--header-h) + var(--s6)) 0 var(--s7)}
.docket .docket-actions{gap:var(--s3) var(--s6)}
.docket .text-link{min-height:56px;color:#fff;font-size:1.0625rem}
@media (max-width:374.98px){.docket .docket-actions{column-gap:var(--s5)}.docket .button{padding-inline:var(--s5)}}
@media (min-width:761px){
  :root{--display:clamp(2.75rem,6.2vw,5.5rem)}
  .docket{padding:calc(var(--header-h) + var(--s8)) 0 var(--s8)}
}
/* Tablets: the headline keeps growing with the screen instead of dropping back at 761px */
@media (min-width:761px) and (max-width:1023.98px){:root{--display:clamp(3.5rem,8.4vw,5rem)}}
/* The employer headline has short lines, so it can run larger */
.hire{--display:clamp(2.5rem,12.5vw,5.5rem)}
/* Wide screens: the two proof numbers stand beside the headline */
@media (min-width:1024px){
  .docket{grid-template-columns:minmax(0,2fr) minmax(min-content,1fr);column-gap:0;align-items:start}
  .docket>*{grid-column:1}
  .docket .docket-facts li{min-width:0;padding-top:var(--s4);border-top:1px solid var(--rule-night)}
  .docket .docket-facts .num{font-size:clamp(3rem,4.4vw,4.5rem)}
}
/* Employer cover: three proofs */
@media (max-width:760.98px){.hire .docket-facts li span{max-width:36ch}}
@media (min-width:761px) and (max-width:1023.98px){.hire .docket .docket-facts{gap:var(--s5) var(--s6)}}
/* The rating wears the reviews' five stars, in the one warm colour that holds on the night */
.docket-facts .rated{grid-template-columns:auto 1fr;justify-content:start;align-items:center;column-gap:var(--s2)}
.docket-facts .rated>span:last-child{grid-column:1/-1}
.docket-facts .stars{color:var(--amber-night);max-width:none}
@media (min-width:1024px){.docket-facts .rated{grid-template-columns:auto}.docket-facts .stars{gap:3px;margin-block:2px var(--s1)}.docket-facts .stars .i{width:20px;height:20px}}
@media (min-width:761px) and (max-width:1023.98px){.docket-facts .rated{grid-template-columns:auto}}
/* The cover is sized to the screen: tall screens show it with the next heading whole under it, short ones show it with a strip of the next section */
@media screen and (min-width:1024px){
  .cover{display:grid;min-height:min(100vh - 11rem,61rem);min-height:min(100svh - 11rem,61rem)}
  .docket{align-content:center}
}
@media screen and (min-width:1024px) and (max-height:50.6875rem){.cover{min-height:calc(100vh - 3rem);min-height:calc(100svh - 3rem)}}
/* Smallest phones (under 340px): both first-screen actions still share one row */
@media (max-width:339.98px){
  .docket .docket-actions{column-gap:var(--s4)}
  .docket .button{padding:0 var(--s4)}
  .docket .button,.docket .text-link{font-size:1rem}
}
/* Demo: flat on paper, one rule under the title */
.try{background:var(--paper);padding-bottom:var(--section)}
.sheet{margin-top:var(--s5);padding:0;background:none;border:0;border-radius:0;box-shadow:none}
.sheet-head{align-items:baseline;justify-content:space-between}
.sheet-head h3{font:400 var(--t-h3d)/1.1 var(--f-serif);letter-spacing:-.015em}

.step-rule .rule-label{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.stamp-checked{padding-inline:0;border-color:transparent;transform:none;margin-right:calc(-2px - .12em)}
@media (prefers-reduced-motion:no-preference){.step.is-stamped .stamp-checked{animation-name:stamp-flat}@keyframes stamp-flat{from{opacity:0;transform:scale(1.15)}to{opacity:1;transform:none}}}
@media (max-width:760.98px){
}
@media (forced-colors:active){.site-header{border-bottom:1px solid CanvasText}dialog.cv{border:1px solid CanvasText}.cv-bar{border-bottom:1px solid CanvasText}.cv .cv-bar button{border:1px solid ButtonText}}
/* What I do: three things, large */
.does{background:var(--mist)}
.tiles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));margin-top:var(--s7);border-top:2px solid var(--ink)}
.tiles li{padding:var(--s6) var(--s6) var(--s7);border-left:1px solid var(--rule)}
.tiles li:first-child{padding-left:0;border-left:0}
.tiles h3{font:400 var(--tile)/1.08 var(--f-serif);letter-spacing:-.015em;text-wrap:balance}
.nb{white-space:nowrap}
.nbs{display:inline-block}
.print-site{display:none}
.tiles p{margin-top:var(--s4);max-width:36ch;font-size:1.0625rem;color:var(--ink-soft)}
.ask{display:grid;gap:var(--s4);padding-top:var(--s6);border-top:1px solid var(--rule)}
.ask b{font:400 var(--t-h3d)/1.1 var(--f-serif);letter-spacing:-.015em}
@media (min-width:761px){.ask b{font-size:clamp(1.5rem,2.1vw,1.75rem)}}
@media (max-width:599.98px){.ask b{font-size:var(--tile)}}
.ask span{font-size:1.0625rem;color:var(--ink-soft)}
@media (min-width:761px){
  .tiles{grid-template-rows:auto auto}
  .tiles li{display:grid;grid-template-rows:subgrid;grid-row:span 2;row-gap:var(--s4);padding-bottom:var(--s6)}
  .tiles li+li{padding-left:calc(var(--s6) - 1px)}
  .tiles p{margin-top:0}
  .ask{grid-template-columns:repeat(3,minmax(0,1fr));align-items:baseline;gap:0}
  .ask span{grid-column:2/4;padding-left:var(--s6)}
}
@media (max-width:760.98px){
  .tiles{grid-template-columns:1fr}
  .tiles li,.tiles li:first-child{padding:var(--s5) 0;border-left:0;border-top:1px solid var(--rule)}
  .tiles li:first-child{border-top:0}
  .tiles p{max-width:62ch}
  .ask{padding-top:var(--s5)}
}
/* Reviews: one large, two short */
.quotes{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);gap:var(--s7) var(--s8);margin-top:var(--s7);align-items:start}
.quote blockquote p{font:400 1.5rem/1.35 var(--f-sans);max-width:26ch}
.quote-lead blockquote p{font:400 var(--tile)/1.15 var(--f-serif);letter-spacing:-.015em;max-width:22ch;text-indent:-.356em}
.reviews-src{margin-top:var(--s7);font-size:var(--t-sm);color:var(--ink-soft)}
.reviews-src .text-link{margin-left:var(--s3)}
@media (min-width:761px){
  .quote blockquote p{max-width:none}
  .quote-lead blockquote p{font-size:clamp(1.75rem,1rem + 2.2vw,3rem);max-width:20ch}
}
@media (max-width:760.98px){
  .quotes{grid-template-columns:1fr;gap:var(--s6)}
  .quote blockquote p{font-size:1.25rem;max-width:none}
  .quote-lead blockquote p{font-size:1.75rem;max-width:none}
  .reviews-src .text-link{display:flex;width:fit-content;margin-left:0}
}
@media (min-width:761px) and (max-width:770.98px){.reviews-src .text-link{display:flex;width:fit-content;margin-left:0}}
@media (min-width:771px) and (max-width:883.98px){body:not(.hire) .reviews-src .text-link{display:flex;width:fit-content;margin-left:0}}
/* Close: the ask, flat on the night, on the tiles' grid */
.close-grid{display:grid;gap:var(--s8);align-items:start}
.close-grid .contact-docket .lead{margin-top:var(--s5);font-size:1.25rem}
.close-grid .contact-docket .mail-link{font-size:clamp(1.5rem,1rem + 1.6vw,2.25rem)}
@media (hover:hover) and (pointer:fine){.mail-link:hover,.footer a:hover{text-decoration-thickness:2px}}
@media (max-width:1023.98px){.close-grid .contact-docket{display:block}}
@media (min-width:1024px){
  .close-grid .contact-docket{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0}
  .close-grid .contact-docket>*{grid-column:2/4;padding-left:var(--s6)}
  .close-grid .contact-docket>h2{grid-column:1;grid-row:1/20;padding-left:0}
  .close-grid .contact-docket .lead{margin-top:calc(var(--h2)*.18 - 9px)}
}
@media (max-width:599.98px){.close-grid .contact-docket .mail-link{font:600 clamp(1.125rem,6.2vw,1.625rem)/1.2 var(--f-sans)}}
@media print{html,.cover{background:none}}
/* Employer page (hire/): the same bands and grid. Work history, what customers said, the AI work, the ask. */
.held{display:grid;gap:var(--s2);padding-top:var(--s6);border-top:1px solid var(--rule);font-weight:600}

@media (min-width:1024px){
  .held{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s2) 0;font-size:1.0625rem}
  .held li+li{padding-left:var(--s6)}
  .held li:nth-child(3n+1){padding-left:0}
}
@media (max-width:1023.98px){.held{padding-top:var(--s5)}}

/* CV window (hire/): the page as a picture over the site. Laid out only while open, so a closed window stays hidden. */
.cv{width:100%;max-width:none;height:100vh;height:100dvh;max-height:none;margin:auto;padding:0;border:0;background:var(--mist);color:var(--ink);overflow:hidden}
.cv:not([open]){display:none}
.cv[open]{display:grid;grid-template-rows:auto minmax(0,1fr)}
.cv::backdrop{background:#081633d9}
html:has(.cv[open]){overflow:hidden;scrollbar-gutter:stable}
.cv-bar{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--s2);padding:0 var(--s3);background:var(--night)}
.cv-bar button{min-width:64px;min-height:56px;padding:0 var(--s4);border:0;background:none;color:var(--paper);font:600 1rem/1 var(--f-sans);cursor:pointer}
.cv-bar :focus-visible{outline-color:var(--paper);outline-offset:-6px}
.cv-mail{display:inline-flex;align-items:center;min-height:56px;margin-right:auto;padding:0 var(--s4);color:var(--paper);font:600 1rem/1 var(--f-sans);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px;white-space:nowrap}
.cv-page{position:relative;overflow:auto;overscroll-behavior:contain}
.cv-page:focus-visible{outline-offset:-3px}
.cv-page picture{display:block}
.cv-page img{display:block;width:100%;height:auto;max-width:none;background:#fff;cursor:zoom-in}
.cv.is-zoomed .cv-page img{width:max(175%,1100px);cursor:zoom-out}
@media (min-width:980px){.cv{width:min(980px,100vw);height:calc(100vh - 2 * var(--s6));height:calc(100dvh - 2 * var(--s6));border-radius:var(--radius-panel);box-shadow:0 0 0 1px var(--rule-night),0 24px 80px #0008}}
@media (prefers-reduced-motion:no-preference){
  .cv[open]{animation:cv-open var(--d-slow) var(--ease-out)}
  .cv[open]::backdrop{animation:cv-fade var(--d-slow) var(--ease-out)}
  @keyframes cv-open{from{opacity:0;transform:scale(.96)}}
  @keyframes cv-fade{from{opacity:0}}
  /* Leaving: where the browser can keep a closing dialog on top (overlay), it fades out instead of vanishing. */
  @supports (overlay:auto){
    .cv,.cv::backdrop{transition:opacity var(--d-base) var(--ease-out),transform var(--d-base) var(--ease-out),overlay var(--d-base) allow-discrete,display var(--d-base) allow-discrete}
    .cv:not([open]),.cv:not([open])::backdrop{opacity:0;pointer-events:none}
    .cv:not([open]){transform:scale(.98)}
  }
}
@media print{.cv{display:none!important}}

.footer-row{row-gap:var(--s3)}
.footer-end{flex-wrap:wrap;gap:var(--s3) var(--s5)}

@media (max-width:760.98px){.footer-end{margin-left:0}}
/* Upright tablets and half-width windows (761 to 1023): three columns are too narrow to read. Tiles become rows, heading left and text right, like the question row under them. The lead review takes the full width with the two short ones side by side beneath. */
@media (min-width:761px) and (max-width:1023.98px){
  .tiles{grid-template-columns:1fr;grid-template-rows:none}
  .tiles li,.tiles li:first-child{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);grid-template-rows:none;grid-row:auto;align-items:baseline;row-gap:0;padding:var(--s5) 0;border-left:0;border-top:1px solid var(--rule)}
  .tiles li:first-child{border-top:0}
  .tiles li+li{padding-left:0}
  .tiles p{margin-top:0;max-width:none;padding-left:var(--s6)}
  .ask{grid-template-columns:minmax(0,5fr) minmax(0,7fr);padding-top:var(--s5)}
  .ask span{grid-column:2}
  .quote-lead{grid-column:1/-1;grid-row:auto}
  .quote-lead blockquote p{max-width:none;text-wrap:balance}
  .step-text{grid-template-columns:1fr}
}
/* End redesign */

/* 404: the cover pattern, white type on the night, the site header above it (round thirteen). */
.nf-body{min-height:100vh;min-height:100dvh;background:var(--night);color:var(--on-night)}
.nf{min-height:100vh;min-height:100dvh;display:grid;align-content:center;padding:calc(var(--header-h) + var(--s7)) 0 var(--s8)}
.nf-card{width:min(100% - 2 * var(--pad),var(--wrap));margin-inline:auto}
.nf-card h1{color:#fff;font-size:clamp(2.5rem,1.5rem + 4vw,5rem);line-height:1.02;letter-spacing:-.025em}
.nf-body-text{margin-top:var(--s5);font-size:1.1875rem;color:var(--night-soft)}
.nf-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3) var(--s6);margin-top:var(--s6)}
.nf-actions .button{min-height:56px;padding:0 var(--s6);background:var(--paper);color:var(--ink);font-size:1.0625rem}
.nf-actions .text-link{color:#fff;overflow-wrap:anywhere}
.nf :focus-visible{outline-color:var(--paper)}

/* States. A press answers with colour at every pointer, and with motion off too. 100ms. */
.button,.text-button,.cv-bar button{transition:background-color var(--d-fast) var(--ease-out),transform var(--d-fast) var(--ease-out)}
.button-ink:active{background:#1c3f72}
.docket .button:active{background:#c5d8ee}
.text-link:active,.text-button:active{color:var(--ink);text-decoration-thickness:2px}
.site-header a:active,.nf-actions .text-link:active,.docket .text-link:active,.contact-docket .mail-link:active,.contact-docket .text-button:active,.contact-docket .text-link:active,.footer a:active{color:var(--night-soft);text-decoration-thickness:2px}
.skip-link:active{background:var(--mist)}

/* Motion off: reduced motion. Colour changes stay; nothing moves. */
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}

@media print{.skip-link,.sheet-actions,.docket-actions,.copy-email,.footer-end,.demo-start{display:none!important}.site-header{position:static;height:auto!important;background:none!important;animation:none!important;color:var(--ink);padding:0 0 12pt}.site-header a:not(.brand){display:none!important}.brand{color:var(--ink)!important}.print-site{display:inline;margin-left:1.5em}.sheet,.step,.quote{break-inside:avoid}.docket,.contact-docket{margin:0;box-shadow:none}.contact{display:block;min-height:0}.contact,.footer{background:none;color:var(--ink)}.footer,.footer p,.footer a{color:var(--ink)!important}}
/* Portrait (2026-11-06): the face beside the first words, on both pages */
.docket{grid-template-columns:minmax(0,1fr) auto;column-gap:var(--s4)}
.docket>*{grid-column:1/-1}
.docket .docket-body{grid-column:1;grid-row:2}
.docket .portrait{grid-column:2;grid-row:2;align-self:start;margin-top:var(--s4);width:clamp(76px,24vw,96px);height:auto;aspect-ratio:4/5;object-fit:cover;object-position:50% 18%;border-radius:var(--radius-panel);background:#12234a}
@media (min-width:761px) and (max-width:1023.98px){.docket .portrait{width:132px;grid-row:2/span 2;margin-top:var(--s5)}.docket .docket-actions{grid-column:1}}
@media (min-width:1024px){
  .docket{--pw:clamp(280px,27vw,360px);grid-template-columns:minmax(0,1fr) var(--pw);column-gap:var(--s7)}
  .docket>*{grid-column:1}
  .docket .docket-body{grid-row:auto}
  .docket .docket-facts{grid-column:1;grid-row:auto;flex-direction:row;flex-wrap:wrap;gap:var(--s5) var(--s7);margin-top:var(--s7);padding-left:0}
  .docket .docket-facts li{padding-top:0;border-top:0}
  .docket .docket-facts li span{max-width:24ch}
  .docket .portrait{grid-column:2;grid-row:1/span 4;align-self:start;margin-top:0;width:100%;height:100%;min-height:420px;max-height:calc(var(--pw)*1.7);aspect-ratio:auto;object-position:50% 14%}
  .hire .docket .docket-facts .num{font-size:clamp(2rem,2.8vw,2.5rem)}
}
@media (min-width:1024px) and (max-height:50.6875rem){.docket{padding-top:calc(var(--header-h) + var(--s6))}}
@media print{.portrait{display:none!important}}
/* Round nine (v102): the same face beside the sign-off, so the last screen is a person, not an empty field */
/* Wide: the heading in the left column; the text column starts level with it. (The small face above it was removed
   7 Nov 2026, Steven: the hero portrait already shows him.) */
@media (min-width:1024px){.close-grid .contact-docket{grid-template-rows:auto auto auto 1fr;align-items:start}.close-grid .contact-docket>h2{grid-row:1/5}.close-grid .contact-docket>.lead{grid-row:1}.close-grid .contact-docket>.contact-mail{grid-row:2}}
/* Round eleven (v105): moving between the two pages is one smooth step, not a flash. Cross-document view transitions
   (CSS View Transitions Level 2): Chrome and Edge 126+, Safari 18.2+; other browsers load the page as before.
   The header stays put, the portrait glides to its new place, the page body fades and rises 12px. Off for reduced motion. */
@media (prefers-reduced-motion:no-preference){
  @view-transition{navigation:auto}
  .site-header{view-transition-name:sj-header}
  .docket .portrait{view-transition-name:sj-portrait}
  ::view-transition-group(*){animation-duration:.42s;animation-timing-function:cubic-bezier(.2,.8,.2,1)}
  ::view-transition-old(root){animation:sj-out .14s cubic-bezier(.4,0,1,1) both}
  ::view-transition-new(root){animation:sj-in .4s cubic-bezier(.2,.8,.2,1) .14s both}
  ::view-transition-old(sj-header),::view-transition-new(sj-header){animation:none}
  @keyframes sj-out{to{opacity:0}}
  @keyframes sj-in{from{opacity:0;transform:translateY(12px)}}
}
/* Round twelve (v106): the demo is a mail client in the site's own materials: paper, mist, 6px corners, the card shadow.
   The list is a stack whose height never changes during a run: emails the assistant files away fade and slide out,
   then leave the layout in one step when the run ends, so nothing on the page shifts (CLS) and the held invoice and
   all three drafts are always in view. Sizes stay on the site's scale (13px labels, 15 to 17px text). */
.sheet.mail{margin-top:var(--s6);padding:0 0 var(--s4);background:var(--paper);border:1px solid var(--rule);border-radius:var(--radius-panel);box-shadow:var(--shadow-card);overflow:hidden}
.mail-bar{display:flex;align-items:baseline;flex-wrap:wrap;gap:var(--s1) var(--s4);padding:var(--s3) var(--s5);background:var(--night);color:var(--on-night)}
.mail-bar h3{flex:1 1 auto;font:600 1rem/1.4 var(--f-sans);letter-spacing:0}
.mail-body{display:grid;grid-template-columns:11rem minmax(0,1fr) minmax(0,1.05fr);align-items:start}
.mail-folders{list-style:none;margin:0;padding:var(--s4) var(--s3);align-self:stretch;border-right:1px solid var(--rule);background:var(--mist);font-size:.9375rem}
.mail-folders li{display:flex;justify-content:space-between;align-items:center;padding:6px 10px;border-radius:4px;color:var(--ink-soft)}
.mail-folders li[data-folder="inbox"]{background:#0a1f3d12;color:var(--ink);font-weight:600}
.mail-folders b{display:inline-block;font-weight:600;font-variant-numeric:tabular-nums;color:var(--ink)}
/* The folder pane is decoration (hidden from screen readers; the result line says the same), so its counts are drawn from data-n. */
.mail-folders b::after{content:attr(data-n)}
.mail-list{list-style:none;margin:0;padding:0;align-self:start;border-right:1px solid var(--rule);background:#fff}
/* Unsorted or sorting: the list is exactly as tall as the sorted inbox, so the window never changes height; the extra
   unsorted mail runs under a soft fade at the bottom. Sorted: no fixed height and no clipping, so a reader's own text
   spacing or a late font can never hide a row. */
.mail:not(.is-sorted) .mail-list{height:var(--sorted-h,auto);overflow:hidden;-webkit-mask-image:linear-gradient(#000 calc(100% - 40px),transparent);mask-image:linear-gradient(#000 calc(100% - 40px),transparent)}
.mail-body{background:#fff}
.msg-in{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:baseline;gap:0 var(--s2);padding:var(--s3) var(--s4) var(--s3) calc(var(--s4) + 8px);position:relative}
.msg-in::before{content:"";position:absolute;left:10px;top:20px;width:7px;height:7px;border-radius:50%;background:var(--blue)}
.msg.is-read .msg-in::before{background:transparent}
.msg-from{font-weight:600;font-size:1rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.msg-time{grid-column:3;font-size:.8125rem;color:var(--ink-soft);font-variant-numeric:tabular-nums}
.msg-subj{grid-column:1/-1;font-size:.9375rem;color:var(--ink-soft)}
/* Tags and drafts hold their space from the start and only fade in, so a run changes no layout. */
.msg-tag{justify-self:start;white-space:nowrap;padding:0 7px;border-radius:4px;font:600 .8125rem/1.6 var(--f-sans);background:#0a1f3d0f;color:var(--ink-soft);visibility:hidden}
.msg.is-tagged .msg-tag{visibility:visible}
.msg[data-kind="booking"] .msg-tag,.msg[data-kind="quote"] .msg-tag{background:#0b63bd17;color:#0a4f97}
.msg.is-flagged{background:#b423180d}
.msg.is-flagged .msg-tag{background:#b423181a;color:#8a1a12}
.msg-draft{grid-column:1/-1;visibility:hidden;margin-top:var(--s2);padding:6px var(--s3);border-left:2px solid var(--blue);font-size:.875rem;line-height:1.45;color:var(--ink-soft);background:var(--paper)}
.msg.is-drafted .msg-draft{visibility:visible}
.msg.is-flagged .msg-draft{visibility:visible;border-left-color:var(--alert);color:var(--ink);font-weight:600}
.msg-held{display:none}.msg.is-flagged .msg-held{display:inline}
/* Filed away: hidden from sight and from screen readers. During a run it keeps its slot until the run ends (is-leaving). */
.msg.is-gone{display:none}
.mail-ai{padding:var(--s4) var(--s5) var(--s3)}
.mail-ai-head{font:600 var(--t-label)/1.3 var(--f-sans);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-soft);padding-bottom:var(--s2);border-bottom:2px solid var(--ink)}
.mail-ai .step{grid-template-columns:1.25rem minmax(0,1fr) 6.5rem;min-height:0;padding:var(--s3) 0;gap:var(--s3)}
.mail-ai .step-result{justify-self:end}
.mail-ai .step-n{font:600 1rem/1.4 var(--f-sans);color:var(--ink-soft)}
.mail-ai .step-text{grid-template-columns:1fr;gap:2px}
.mail-ai .step-do{font-size:1rem;line-height:1.4;text-wrap:pretty}
.mail-ai .step-text{min-width:0}
.mail-ai .step-rule{font-size:.9375rem}
.mail-ai .stamp{font-size:var(--t-label);padding:4px 8px 3px}
.mail .sheet-actions{display:grid;grid-template-columns:1fr auto;align-items:center;gap:var(--s2) var(--s5);padding:0 var(--s5);margin-top:var(--s2)}
/* Skip and replay share one cell (right on wide screens, under the link on phones). The cell keeps its size while both
   are hidden, so the window never changes height; the email link stays first at every width. */
.mail .sheet-actions .text-button{grid-area:1/2;justify-self:end}
.js .mail .sheet-actions .text-button[hidden]{display:inline-flex;visibility:hidden}
@media (prefers-reduced-motion:no-preference){
  .msg{transition:opacity .28s var(--ease-out),transform .28s var(--ease-out),background-color .3s var(--ease-out)}
  .msg.is-leaving{visibility:visible;opacity:0;transform:translateX(24px);pointer-events:none}
  .msg-in::before{transition:background-color .25s}
  .msg.is-tagged .msg-tag,.msg.is-flagged .msg-draft,.msg.is-drafted .msg-draft{animation:type var(--d-slow) var(--ease-out) both}
  .mail-folders li.bump b{animation:bump .36s var(--ease-out)}
  @keyframes bump{40%{transform:scale(1.25);color:var(--blue)}}
}
@media (forced-colors:active){
  .stamp-checked{border-color:Canvas}
  .msg.is-flagged{outline:2px solid CanvasText;outline-offset:-2px}
  .msg-tag{border:1px solid CanvasText}
  .mail-folders li[data-folder="inbox"]{outline:1px solid CanvasText}
}
@media (max-width:1023.98px){
  .mail-body{grid-template-columns:1fr}
  .mail-folders{display:none}
  .mail-list{border-right:0;border-bottom:1px solid var(--rule)}
}
@media (max-width:760.98px){
  .mail-bar{padding:var(--s3) var(--s4)}
  .mail-ai{padding:var(--s4)}
  .mail .sheet-actions{padding:0 var(--s4);grid-template-columns:auto}
  .mail .sheet-actions .text-button{grid-area:2/1;justify-self:start}
  .mail-ai .step{grid-template-columns:minmax(0,1fr) auto;gap:var(--s1) var(--s3)}
  .mail-ai .step-n{display:none}
  .mail-ai .step-text{grid-column:1}
  .mail-ai .step-result{grid-column:2;grid-row:1}
}
@media print{.mail-list,.mail-folders{display:none}.mail-body{display:block}}
/* Round thirteen (v106): phones with a notch or a home indicator. viewport-fit=cover lets the night bars run under them;
   these pads keep the text out from under them. env() is 0 everywhere else, so nothing moves on a desktop. */
.site-header{height:calc(var(--header-h) + env(safe-area-inset-top));padding-top:env(safe-area-inset-top)}
:root{--pad:max(clamp(20px,4vw,48px),env(safe-area-inset-left),env(safe-area-inset-right))}
.footer{padding-bottom:env(safe-area-inset-bottom)}
.cv-bar{padding-top:env(safe-area-inset-top);padding-left:max(var(--s3),env(safe-area-inset-left));padding-right:max(var(--s3),env(safe-area-inset-right))}
.cv-page{padding-bottom:env(safe-area-inset-bottom)}
.cv:focus-visible{outline:3px solid var(--paper);outline-offset:-3px}
/* Hire page, 1024 to 1279: the three proof figures stay on one row instead of splitting two and one. */
@media (min-width:1024px) and (max-width:1279.98px){.hire .docket .docket-facts{column-gap:var(--s5)}.hire .docket .docket-facts .num{font-size:2rem}}
/* While the run is going, the space a draft will fill shows a faint placeholder, so it reads as "not written yet". */
.msg-draft{position:relative}

/* Round two of the audit loop. 1024 to 1199: the decorative folder pane goes, so inbox and steps get the width. */
@media (min-width:1024px) and (max-width:1199.98px){.mail-body{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr)}.mail-folders{display:none}}
/* Narrow phones and large text: the tag drops under the sender instead of running into the time. */
@media (max-width:399.98px){.msg-in{grid-template-columns:minmax(0,1fr) auto}.msg-from{grid-column:1;grid-row:1}.msg-time{grid-column:2;grid-row:1}.msg-subj{grid-row:2}.msg-tag{grid-column:1/-1;grid-row:3;margin-top:4px}.msg-draft{grid-row:4}
  .mail-ai-head{letter-spacing:.06em}.mail .sheet-end{min-height:3lh}}
/* Phones: the phone CV is already laid out to read at full width, so Zoom only needs to double it. */
@media (max-width:979.98px){.cv.is-zoomed .cv-page img{width:200%}}
/* Rows that fade and leave mid-run must never be the browser's scroll anchor, or the page jumps as they go. */
.mail-list,.mail .msg{overflow-anchor:none}
/* Print: the demo prints its finished result even if it never played; the 404 prints dark on white; the hero stays on the page's left edge. */
@media print{
  .step.is-pending .step-do,.step.is-pending .step-n,.step.is-pending .step-rule,.step.is-pending .stamp,.step.is-pending .step-note,.running .step .stamp,.running .step .step-note,.running .sheet-end{opacity:1!important}
  .nf-body,.nf{min-height:0;background:none;color:var(--ink)}.nf{padding:0}
  .nf-card h1,.nf-body-text,.nf-actions .text-link{color:var(--ink)!important}
  .docket{margin-inline:auto}
}
/* Arriving on the CV window: the cover portrait does not fly across, because the window opens over it. */
html.to-cv .docket .portrait{view-transition-name:none}
.reviews-src{font-size:.9375rem}
@media (max-width:1023.98px){.quote-lead{grid-row:auto}}
/* CV window: download the CV as PDF or Word (round fourteen). Same weight as the bar's buttons. */
.cv-dl{display:inline-flex;align-items:center;min-height:56px;min-width:56px;justify-content:center;padding:0 var(--s3);color:var(--paper);font:600 1rem/1 var(--f-sans);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px}
/* Narrow phones: Email me, PDF, Word, Zoom and Close stay on one row, each still at least 44px. */
/* The first short review starts on the lead review's cap line (wide screens), with the new quotes. */
/* Round fifteen. Unsorted inbox reads like a real inbox: rows are compact until the assistant writes into them, then
   the draft or held note opens in place. The list itself is held at its sorted height while unsorted or sorting, so
   these openings happen inside it and nothing below the window moves. */
/* Draft slots are reserved before the run too (7 Nov sweep): starting the run must not move a single row. */
.mail:not(.is-sorted):not(.running) .msg:not(.is-drafted):not(.is-flagged) .msg-draft{visibility:hidden}
.mail.running .msg:not(.is-drafted):not(.is-flagged) .msg-draft{visibility:hidden}
.mail:not(.is-sorted) .msg:not(.is-tagged) .msg-tag{visibility:hidden}
/* Narrow screens: the folder counts sit above the steps, so the inbox visibly responds to each step. */
@media (max-width:1023.98px){
  .mail-ai .mail-strip{display:flex;flex-wrap:wrap;gap:var(--s1) var(--s4);margin:0 0 var(--s3);padding:var(--s2) var(--s3);border-radius:4px;background:var(--mist);font-size:.875rem;color:var(--ink-soft)}
  .mail-strip b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
  .mail-strip b::after{content:attr(data-n)}
}
.mail-strip{display:none}
/* Round fifteen: reviews as cards, so they read as Google reviews at a glance. Paper on the mist band, the site's 6px
   corners and card shadow; the reviewer's initial, name, stars and a small Google mark sit under each quote. */
.quotes{align-items:stretch}
.quote figure{height:100%;display:flex;flex-direction:column;justify-content:space-between;gap:var(--s4);padding:var(--s5) var(--s5) var(--s4)!important;background:var(--paper);border:1px solid var(--rule)!important;border-radius:var(--radius-panel);box-shadow:var(--shadow-card)}
.quote-lead figure{padding:var(--s6) var(--s6) var(--s5)!important}
.quote blockquote p{text-indent:-.426em}
.quote figcaption{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;column-gap:var(--s3);align-items:center;margin-top:0}
.quote figcaption .rv-av{grid-row:1/3;display:grid;place-items:center;width:36px;height:36px;border-radius:50%;background:var(--ink);color:var(--paper);font:600 .9375rem/1 var(--f-sans)}
.quote figcaption b{grid-column:2;grid-row:1;font-weight:600}
.quote figcaption .stars{grid-column:2;grid-row:2}
.quote figcaption .rv-g{grid-column:3;grid-row:1/3;width:20px;height:20px}
.quote:not(.quote-lead){padding-left:0!important}
@media (min-width:1024px){.quote:not(.quote-lead){margin-top:0}.quotes{gap:var(--s5) var(--s6)}}
@media (max-width:1023.98px){.quotes{gap:var(--s4)}}
@media print{.quote figure{box-shadow:none}}
@media (min-width:1024px){
  .quotes{grid-template-columns:repeat(3,minmax(0,1fr))}
  .quote-lead{grid-column:1/-1;grid-row:auto}
  .quote-lead blockquote p{max-width:34ch}
}
@media print{.section h2{break-after:avoid}.step,.quote{break-inside:avoid}.try-next{break-before:avoid}}
.rv-av::before{content:attr(data-i)}
/* Narrow phones: the tag has its own line, so keep that line reserved before tagging (no shift inside the list). */
@media print{.reviews-src{break-inside:avoid}.reviews-src .text-link{display:none!important}}
@media (min-width:761px) and (max-width:1023.98px){.quotes>.quote:last-child{grid-column:1/-1}}
.print-cv{display:none}
@media print{.print-cv{display:block;margin-top:8pt;color:var(--ink)!important}}
/* CV window toolbar (round seventeen, Steven): icon buttons like a desktop window: download with a file-type tag,
   a magnifier for Zoom, an X for Close. 44px targets, a quiet hover and pressed tint, a visible focus ring. */
.cv-bar{align-items:center;gap:var(--s1)}
.cv-bar [data-ico]{position:relative;display:inline-grid;place-items:center;width:48px;height:48px;min-width:48px;min-height:48px;margin-block:4px;padding:0!important;border:0;border-radius:8px;background:none;color:var(--paper);text-decoration:none;cursor:pointer}
.cv-bar [data-ico] .ico{width:22px;height:22px}
.cv-dl .ico{transform:translateY(-3px)}
.ftag{position:absolute;left:50%;bottom:2px;transform:translateX(-50%);padding:0 3px;border-radius:2px;color:#fff;font:700 10px/13px var(--f-sans);letter-spacing:.03em}

.cv-bar [data-ico]:active{background:#fbfaf633}
@media (hover:hover) and (pointer:fine){.cv-bar [data-ico]:hover{background:#fbfaf61f}}
.cv-bar [data-ico]:focus-visible{outline:3px solid var(--paper);outline-offset:-3px}
.cv-close{margin-left:var(--s2)}
@media (max-width:399.98px){.cv-bar [data-ico]{width:44px;height:44px;min-width:44px;min-height:44px}.cv-bar{gap:2px}}
.ftag-pdf{background:#c5221f}.ftag-doc{background:#1a5fb4}
.cv-bar .cv-mail[data-ico]{margin-right:auto;text-decoration:none}
/* Live demo panel (round seventeen): plain words, big type and big targets for older readers. */
.live-picks{display:flex;flex-wrap:wrap;gap:var(--s2);margin-top:var(--s5)}
.live-pick{min-height:48px;padding:0 var(--s4);border:1px solid #0a1f3d40;border-radius:999px;background:#fff;color:var(--ink);font:600 1rem/1.3 var(--f-sans);cursor:pointer}
.live-form{display:grid;gap:var(--s1);margin-top:var(--s5);max-width:720px}
.live-form input,.live-form textarea{width:100%;min-height:52px;padding:12px 14px;border:1px solid #0a1f3d59;border-radius:6px;background:#fff;color:var(--ink);font:400 1.0625rem/1.5 var(--f-sans)}
.live-form textarea{resize:vertical;min-height:8rem}
.live-go{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3) var(--s4);margin-top:var(--s4)}
.live-wait::after{content:"";display:inline-block;width:1em}
.live-card{display:grid;gap:var(--s4);padding:var(--s5);border:1px solid var(--rule);border-left:4px solid var(--ink-soft);border-radius:var(--radius-panel);background:#fff}
.live-k{font:600 var(--t-label)/1.3 var(--f-sans);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft)}
.live-rule{position:relative;padding-right:7rem}
.live-rule .stamp{position:absolute;right:0;top:0}
.live-draft-text{margin:6px 0 var(--s4);font-size:1.0625rem;white-space:pre-wrap}
@media print{.try-live{display:none}}
/* The start button lives in the window's title bar, so it never covers the emails (Steven: they choose when it starts). */
.mail-bar .demo-start{order:3;min-height:48px;padding:0 var(--s5);border:0;border-radius:6px;background:var(--paper);color:var(--ink);font:600 1.0625rem/1 var(--f-sans);cursor:pointer;box-shadow:0 0 0 3px #f0a94a66}
.mail-bar .demo-start[hidden]{display:none}
.mail-bar .demo-start:active{transform:scale(.98)}
@media (max-width:760.98px){.mail-bar .demo-start{width:100%;margin-top:var(--s2)}}
.try-lead{margin-top:var(--s4);max-width:62ch;font-size:1.1875rem;line-height:1.55;color:var(--ink-soft)}
.live-form input,.live-form textarea,.live-pick{scroll-margin-block:calc(var(--header-h) + var(--s4)) var(--s6)}
/* Phones: rows="4" made it 128px, too tall for a short screen to show its focus ring (9 Nov, when the panel went live). */
@media (max-width:599.98px){.live-form textarea{min-height:6rem;height:6rem}}
.mail-ai .step{align-items:start}
.mail-ai .step-n{line-height:1.4}
.mail-ai .step-result{align-self:center}
.live-card>.button,.live-draft>.button{justify-self:start;width:auto}
.live-rule{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px;padding-right:0}
.live-rule .live-k{flex:0 0 100%}
.live-rule .stamp{position:static}
/* One control: when the title-bar button is there (scripts on), the bottom copies of it stay out of sight. They remain
   in the page as the no-title-button fallback. */
.mail:has(#demo-start) .sheet-actions .text-button{display:none!important}
.live-v,.live-draft-text{max-width:62ch}
@media (prefers-reduced-motion:no-preference){.live-wait{animation:live-pulse 1.2s ease-in-out infinite}@keyframes live-pulse{50%{opacity:.45}}}
.quote:not(.quote-lead) blockquote p{text-wrap:pretty}
.quote figcaption{margin-top:auto}
/* Portrait v12 (Steven, 8 Nov 2026): his new headshot on dark blue in five navy shades on a regular 4x4 grid (ordered
   dither, style E, his pick of six), fading into the navy; no outline. Cut out with a learned portrait matte; ears and hairline straight from the photo. Each file is
   drawn at the device scale it is shown at (1x, 2x, 3x), so dots stay crisp and the line smooth (tools/make_portraits.py).
   Earlier sets (v4 print, v5 cut-out, v6 soft fade, v7 full sticker) are in git history. */
.portrait-pic{display:contents}
.portrait-pic>source{display:none}  /* <source> must never take a grid cell in the hero grid */
.docket .portrait{width:80px;height:100px;aspect-ratio:auto;object-fit:fill;border-radius:0;background:none;box-shadow:none}
@media (min-width:360px){.docket .portrait{width:96px;height:120px}}

@media (min-width:761px){
  .cover{container-type:inline-size}  /* percentages in 'right' are of the cover's width; cqw names it explicitly */
  /* Desktop: the print stands in the hero's bottom-right corner, its bottom on the hero's bottom edge and its right
     edge on the content edge (the same line as the header's right-hand link). One fixed size per width tier. */
  .cover{position:relative}
  .docket{position:static}
  .docket>:not(.portrait-pic){position:relative;z-index:1}
  .docket .portrait{position:absolute;bottom:0;right:max(var(--pad),(100cqw - var(--wrap)) / 2);margin:0;
    width:300px;height:500px;min-height:0;max-height:none;max-width:none;object-fit:fill;background:none}
}
/* Tablets (761-1023): the same corner placement, a smaller print; the text column stops 32px short of it. */
@media (min-width:761px) and (max-width:1023.98px){.docket .portrait{width:240px;height:400px}
  .docket>:not(.portrait-pic):not(h1){max-width:calc(100% - 240px - var(--s6))}}
@media (min-width:1280px){.docket .portrait{width:360px;height:600px}}
@media (min-width:1440px){.docket .portrait{width:380px;height:634px}}
@media (max-width:359.98px){.quote-lead blockquote p{font-size:1.375rem;line-height:1.2}}
/* ===== Round 25 (Steven): the inbox demo as a macOS window. =====
   A light unified title bar with the three traffic lights, 10px window corners, a soft layered shadow, a quiet grey
   sidebar and hairline dividers. The site's own type and colours stay. The email link sits outside the window. */
.sheet.mail{padding:0;border:1px solid #0a1f3d24;border-radius:12px;overflow:hidden;background:#fff;
  box-shadow:0 0 0 .5px #0a1f3d14,0 2px 6px #0a1f3d14,0 22px 48px -12px #0a1f3d40}
.mail-bar{align-items:center;gap:12px;padding:10px 14px;border-radius:0;background:linear-gradient(#f6f6f6,#ececec);border-bottom:1px solid #d6d6d6;color:var(--ink)}
.mac-lights{display:inline-flex;gap:8px;flex:none}
.mac-lights i{width:12px;height:12px;border-radius:50%;box-shadow:inset 0 0 0 .5px #0000002e}
.mac-lights i:nth-child(1){background:#ff5f57}.mac-lights i:nth-child(2){background:#febc2e}.mac-lights i:nth-child(3){background:#28c840}
.mail-bar h3{flex:1 1 auto;font:600 .9375rem/1.3 var(--f-sans);color:#1d1d1f;text-align:center}
/* The one control: a macOS push button (blue default) at the right of the title bar. */
.mail-bar .demo-start{min-height:34px;padding:0 16px;border:0;border-radius:7px;background:linear-gradient(#3b8cf5,#0a6ae0);color:#fff;font:600 .9375rem/1 var(--f-sans);
  box-shadow:0 1px 2px #0a1f3d33,inset 0 .5px 0 #ffffff59}
/* Sidebar: Mail-style source list. */
.mail-folders li{border-radius:6px}
.mail-folders li[data-folder="inbox"]{background:#0a6ae01f;color:#1d1d1f}
.msg{border-bottom:1px solid #ececf0}
.mail .sheet-actions{display:none}
/* Outside the window: one plain line with the email link. */
.try-next{margin-top:var(--s5);font-size:1.0625rem;color:var(--ink-soft)}
.try-next .text-link{margin-left:6px}
@media (max-width:760.98px){
  .mail-bar{display:grid;grid-template-columns:auto minmax(0,1fr);row-gap:8px}
  .mail-bar h3{text-align:left}
  .mail-bar .demo-start{grid-column:1/-1;width:100%}
  .try-next .text-link{display:inline-flex;margin-left:0}
}
/* The live panel: a second window in the same style. */
.try-live{padding:0;border:1px solid #0a1f3d24;border-radius:12px;overflow:hidden;background:#fff;box-shadow:0 0 0 .5px #0a1f3d14,0 2px 6px #0a1f3d14,0 22px 48px -12px #0a1f3d40}
.try-live>h3{margin:0;padding:10px 14px;background:linear-gradient(#f6f6f6,#ececec);border-bottom:1px solid #d6d6d6;font:600 .9375rem/1.3 var(--f-sans);color:#1d1d1f;letter-spacing:0;text-align:center}
.try-live>.live-lead,.try-live>.live-picks,.try-live>.live-form,.try-live>.live-out{margin-inline:var(--s5)}
.try-live>.live-lead{margin-top:var(--s4)}
@media (max-width:599.98px){.try-live>.live-lead,.try-live>.live-picks,.try-live>.live-form,.try-live>.live-out{margin-inline:var(--s4)}}
@media print{.sheet.mail,.try-live{box-shadow:none}}
.try-live>h3{position:relative}
.try-live>h3 .mac-lights{position:absolute;left:14px;top:50%;transform:translateY(-50%)}
/* Round 25 (Steven): the result is a macOS sheet inside the window: after a run it drops from under the title bar
   over a dimmed window, and OK puts it away. Without scripts or with reduced motion it is a plain panel under the panes. */
.sheet.mail{position:relative}
.mac-alert{display:grid;justify-items:center;padding:var(--s5) var(--s4);border-top:1px solid #e3e3e6;background:#fafafa}
.mac-alert-box{display:grid;justify-items:center;gap:10px;max-width:22rem;text-align:center}
.mac-alert-icon{width:44px;height:44px}
.mac-alert-title{font:700 1.0625rem/1.3 var(--f-sans);color:#1d1d1f}
.mail .mac-alert .sheet-end{margin:0;padding:0;border:0;background:none;min-height:0;font:400 .9375rem/1.45 var(--f-sans);color:#3a3a3c}
.mac-alert-buttons{display:flex;gap:10px;width:100%;margin-top:6px}
.mac-btn{flex:1;min-height:40px;padding:0 14px;border:0;border-radius:8px;background:#e9e9ed;color:#1d1d1f;font:600 1rem/1 var(--f-sans);cursor:pointer;box-shadow:inset 0 0 0 .5px #0000001f}
/* In the window: a dim layer over the panes and the sheet hanging from the title bar. */
.js .mail.alert-float .mac-alert{position:absolute;z-index:5;inset:var(--bar-h,58px) 0 0;display:none;align-items:center;justify-items:center;padding:16px;border:0;border-radius:0 0 10px 10px;background:#1d1d1f33}
.js .mail.alert-float .mac-alert.is-open{display:grid}
/* 7 Nov 2026 (Steven): the result is a centred dialog inside the window (a macOS alert), not a sheet hanging from
   the title bar. On a phone, where the window is taller than the screen, it is centred on the visible part of the
   window instead (--alert-y, set by jobsheet.js). */
.js .mail.alert-float .mac-alert-box{width:min(320px,100%);max-width:none;margin:0;padding:22px 20px 16px;border-radius:12px;background:#f6f6f6;
  box-shadow:0 0 0 .5px #0000002e,0 24px 48px -12px #0a1f3d73;align-self:var(--alert-align,center);margin-top:var(--alert-y,0)}
@media (prefers-reduced-motion:no-preference){
  .js .mail.alert-float .mac-alert.is-open{animation:mac-dim .2s ease-out}
  .js .mail.alert-float .mac-alert.is-open .mac-alert-box{animation:mac-drop .28s cubic-bezier(.2,.8,.25,1)}
  @keyframes mac-dim{from{background:#1d1d1f00}}
  @keyframes mac-drop{from{transform:scale(.96);opacity:0}}
}
@media (forced-colors:active){.js .mail.alert-float .mac-alert-box{border:1px solid CanvasText}}
@media print{.js .mail.alert-float .mac-alert,.mail .mac-alert{position:static;display:grid!important;background:none}.mac-alert-buttons{display:none}}
/* Mail chrome (round 25): a search field in the title bar and a reading-pane feel. */
.mail-bar .mac-search{display:inline-flex;align-items:center;gap:6px;min-width:0;padding:5px 10px;border-radius:7px;background:#e3e3e8;color:#8a8a8e;font-size:.875rem}
.mail-bar .mac-search svg{width:13px;height:13px;flex:none}
@media (max-width:760.98px){.mail-bar .mac-search{display:none}}
.mail-folders li[data-folder]::before{content:"";flex:none;width:14px;height:12px;margin-right:8px;border-radius:2px;background:#0a6ae0;opacity:.75;
  -webkit-mask:linear-gradient(#000 0 0) 0 2px/14px 10px no-repeat,linear-gradient(#000 0 0) 0 0/6px 3px no-repeat;mask:linear-gradient(#000 0 0) 0 2px/14px 10px no-repeat,linear-gradient(#000 0 0) 0 0/6px 3px no-repeat}
.mail-folders li{justify-content:flex-start}
.mail-folders li b{margin-left:auto}
.msg.is-flagged{box-shadow:inset 3px 0 0 var(--alert)}
/* Round 25 tidy (Steven: colour coding, gradients, alignment). One accent family for every control in the windows:
   --mac-blue #0a5fcf (5.2:1 white on it), hover #0952b4, pressed #084594, tint #0a5fcf1a. No gradients on buttons
   (flat, like current macOS); the title bar keeps one quiet vertical gradient. Text greys meet 4.5:1 on their grounds. */
.sheet.mail,.try-live{--mac-blue:#0a5fcf;--mac-blue-hover:#0952b4;--mac-blue-down:#084594;--mac-tint:#0a5fcf1a;--mac-bar:linear-gradient(#f7f7f8,#ededf0);--mac-line:#d9d9de;--mac-sub:#5c5c62}
.mail-bar,.try-live>h3{background:var(--mac-bar);border-bottom:1px solid var(--mac-line)}
.mail-bar .demo-start,.mac-btn-default,.live-go .button{background:var(--mac-blue);color:#fff;border:0;border-radius:8px;box-shadow:0 1px 1.5px #0a1f3d2e}
@media (hover:hover) and (pointer:fine){.mail-bar .demo-start:hover,.mac-btn-default:hover,.live-go .button:hover{background:var(--mac-blue-hover)}}
.mail-bar .demo-start:active,.mac-btn-default:active,.live-go .button:active{background:var(--mac-blue-down)}
.mail-bar .demo-start:focus-visible,.mac-btn:focus-visible,.live-go .button:focus-visible{outline:3px solid var(--blue);outline-offset:2px}
.mail-bar .mac-search{color:var(--mac-sub);background:#e6e6eb}
.mail-folders li[data-folder="inbox"]{background:var(--mac-tint)}
.mail-folders li[data-folder]::before{background:var(--mac-blue);opacity:1}
.msg-in::before{background:var(--mac-blue)}
.mail-folders{background:#f5f5f7;border-right:1px solid var(--mac-line)}
.mail-list{border-right:1px solid var(--mac-line)}
/* Alignment: the title bar is one 52px row on wide screens; lights, title, search and button share its centre line,
   and its left/right padding equals the panes' 20px inset. */
@media (min-width:761px){
  .mail-bar{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;min-height:52px;padding:0 20px;gap:12px}
  .mail-bar .mac-lights{grid-column:1;justify-self:start}
  .mail-bar h3{grid-column:2;text-align:center;white-space:nowrap}
  .mail-bar .mac-search,.mail-bar .demo-start{grid-row:1}
  .mail-bar .mac-search{grid-column:3;justify-self:end;margin-right:calc(var(--btn-w,136px) + 12px)}
  .mail-bar .demo-start{grid-column:3;justify-self:end;min-height:32px;width:var(--btn-w,136px);padding:0}
  .try-live>h3{min-height:52px;display:grid;place-items:center;padding:0 20px}
  .try-live>h3 .mac-lights{left:20px}
}
.mail-bar .mac-search{min-height:32px;box-sizing:border-box}
/* Round 27 fixes (live scoring v109). */
/* The OK button only exists for the floating sheet; without scripts or with reduced motion the result is a plain panel. */
.mail:not(.alert-float) .mac-alert-buttons{display:none}
/* "What I do": three equal text measures. Columns 2 and 3 carry a left inset (--s6) the first does not, so they are
   that much wider: c1 = (100% - 2 x inset) / 3, c2 = c3 = c1 + inset. */
@media (min-width:1280px){body:not(.hire) .tiles{grid-template-columns:calc((100% - 2 * var(--s6)) / 3) calc((100% - 2 * var(--s6)) / 3 + var(--s6)) calc((100% - 2 * var(--s6)) / 3 + var(--s6))}}
/* Before the first run (Steven OK'd, 7 Nov): each step shows its rule in the soft ink, so the list reads as the plan
   rather than rows with gaps. Same space as during the run (nothing moves when it starts). Mid-run the steps to come
   keep their rule hidden until stamped, as before. */
.mail:not(.running):not(.is-sorted) .step.is-pending .step-rule{opacity:1;color:var(--ink-soft)}
.mail:not(.running):not(.is-sorted) .step.is-pending .step-rule .rule-label{color:var(--ink-soft)}
.mail:not(.running):not(.is-sorted) .step.is-pending .step-note{visibility:hidden}
/* Round 29 (live scoring v111). */
/* Opened by a click, a tap or an arrival from a link: no ring on any toolbar control until a key is pressed. */
.cv.by-pointer .cv-bar [data-ico]:focus-visible{outline:0}
/* Bug sweep, 7 Nov 2026. */
/* Pending steps: the result is not announced before it is shown. */
.step.is-pending .step-result .sr-only{display:none}
/* Sorted inbox (1024+): the list pane runs to the bottom of the window. */
@media (min-width:1024px){.mail.is-sorted .mail-list{align-self:stretch}}
/* "Files that can't leave the office?" lines up with the equal-measure tile columns above it (home, 1280+). */
@media (min-width:1280px){body:not(.hire) .ask{grid-template-columns:calc((100% - 2 * var(--s6)) / 3) calc((100% - 2 * var(--s6)) / 3 + var(--s6)) calc((100% - 2 * var(--s6)) / 3 + var(--s6))}}
/* The copy button keeps the width of its longer label, so the line never re-wraps when it says "Email address copied". */
@media (min-width:1024px) and (max-width:1099.98px){.copy-email{min-width:11.5em;justify-content:flex-start}.close-grid .contact-docket .mail-link{font-size:2.125rem}}
/* The header name never wraps; on small phones the employer page's longer link gets a little smaller. */
.brand{white-space:nowrap}
/* Small phones: the employer page's longer link may wrap to two right-aligned lines; it never runs off the screen. */
@media (max-width:399.98px){.hire .header-employers{white-space:normal;text-align:right;line-height:1.25;max-width:9.5em;font-size:min(.9375rem,3.9vw)}}
/* After a mouse close, the CV opener takes focus back without the keyboard ring (Safari). */
.quiet:focus-visible{outline:0}
/* Printing: the result sheet prints flat, never mid-drop over the steps. */
@media print{.mac-alert,.mac-alert-box{animation:none!important;transform:none!important}}
/* Contact, 7 Nov 2026 (Steven: "should it be a button?"). Copy stays: visitors with no mail app need it. It is now a
   quiet pill with a copy icon */
.contact-docket .copy-email{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 16px;border-radius:999px;
  box-shadow:inset 0 0 0 1px #ffffff47;text-decoration:none;font-size:.9375rem;color:var(--on-night);white-space:nowrap}
.contact-docket .copy-email::before{content:"";width:16px;height:16px;flex:none;background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.6' stroke-linejoin='round'%3E%3Crect x='5.5' y='5.5' width='8.5' height='8.5' rx='1.6'/%3E%3Cpath d='M10.5 5.5V3.6A1.6 1.6 0 0 0 8.9 2H3.6A1.6 1.6 0 0 0 2 3.6v5.3a1.6 1.6 0 0 0 1.6 1.6h1.9'/%3E%3C/svg%3E") center/16px no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.6' stroke-linejoin='round'%3E%3Crect x='5.5' y='5.5' width='8.5' height='8.5' rx='1.6'/%3E%3Cpath d='M10.5 5.5V3.6A1.6 1.6 0 0 0 8.9 2H3.6A1.6 1.6 0 0 0 2 3.6v5.3a1.6 1.6 0 0 0 1.6 1.6h1.9'/%3E%3C/svg%3E") center/16px no-repeat}
@media (hover:hover) and (pointer:fine){.contact-docket .copy-email:hover{background:#ffffff14;text-decoration:none}}
.contact-docket .copy-email:active{background:#ffffff1f}
.contact-docket .copy-email:focus-visible{outline:3px solid var(--on-night);outline-offset:3px}
@media (forced-colors:active){.contact-docket .copy-email{border:1px solid ButtonText}.contact-docket .copy-email::before{background:ButtonText}}
.contact-docket .copy-email[hidden]{display:none}  /* shown only when scripts can copy */
/* Print: the hero takes only the space it needs, headings stay with their first block, the review source with the
   reviews (live scoring v115). */
@media print{.cover{min-height:0!important}.docket{padding-block:0 12pt!important}
  .section h2,.section h2+*{break-after:avoid;break-inside:avoid}.reviews-src{break-before:avoid}}
/* Email previews (Steven, 8 Nov: "fill it out like real emails"). Every row shows the first two lines of the message,
   like a real mail client. The assistant's draft or held note shares the same grid cell: before the run the preview is
   shown, when the draft lands it replaces the preview in place. The cell is as tall as the larger of the two, so a run
   moves nothing and there is no empty band before it. */
.msg-prev{grid-column:1/-1;grid-row:3;margin-top:2px;font-size:.875rem;line-height:1.45;color:#5b6675;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.msg-in>.msg-draft{grid-row:3;align-self:start}
.msg.is-drafted .msg-prev,.msg.is-flagged .msg-prev{visibility:hidden}
/* Phones: the tag sits beside the subject (right column), so it takes no line of its own before it appears. */
@media (max-width:399.98px){.msg-in>.msg-subj{grid-column:1;grid-row:2}.msg-in>.msg-tag{grid-column:2;grid-row:2;justify-self:end;align-self:start;margin-top:2px}.msg-prev,.msg-in>.msg-draft{grid-row:3}}
@media print{.msg-prev{display:none}}
/* Live scoring v126 (8 Nov). */
/* "Sort my inbox" is a full 44px target on touch screens, like every other button. */
@media (pointer:coarse),(max-width:760.98px){.mail-bar .demo-start{min-height:44px}}
/* Employer hero figures on tablets: one column (three across would run under the portrait), never one plus two. */
@media (min-width:700px) and (max-width:1023.98px){.hire .docket .docket-facts{display:grid;grid-template-columns:1fr;row-gap:var(--s4)}}
/* Before the run, a row whose draft or held note is taller than two preview lines shows more of the preview, so the
   reserved space is filled with the email itself, not left blank (three lines for the held invoice, four on phones). */
.msg[data-kind="scam"] .msg-prev{-webkit-line-clamp:3}
@media (max-width:599.98px){.msg[data-kind="scam"] .msg-prev{-webkit-line-clamp:5}.msg[data-kind="booking"] .msg-prev{-webkit-line-clamp:3}}
/* Print (8 Nov): only small blocks are kept whole. The demo window and a section's first block may split across a
   page, so no page is left holding one short line. */
@media print{.sheet,.mail,.mail-list,#sheet-steps,.ask,.section h2+*{break-inside:auto!important}.section{break-inside:auto}
  .msg,.step,.quote,.tiles li,.held li{break-inside:avoid}.cover{break-after:auto}}
/* Previews sit inside the same box the draft or held note will fill (same top and bottom padding), so before the run the
   email text fills that box exactly instead of leaving a band below it. */
.msg:has(.msg-draft) .msg-prev{margin-top:var(--s2);padding:6px 0;min-height:0}
.msg[data-kind="scam"] .msg-prev{padding:6px 0}
/* Checks row (Steven, 8 Nov: the blue ticks looked out of place). Set as small capitals, the page's label style (like
   the demo's step heading), so the three read as credentials. Still on the three tile columns. Small caps by font
   feature, not text-transform, so the words themselves (and what is copied or read aloud) stay as written. */
.held{font:600 1rem/1.4 var(--f-sans);font-variant-caps:all-small-caps;letter-spacing:.08em;color:var(--ink-soft)}
/* Sign-off audit (8 Nov). Reviews from 761 to 1023: one column, so the three smaller cards never split two plus one. */
@media (min-width:761px) and (max-width:1023.98px){.quotes{grid-template-columns:1fr}.quote-lead{grid-column:auto}}
/* Header link on phones stays on one line (the employer page's link is longer than the home page's). */
/* The employer page's header link stays on one line from 360px up (it wrapped on most phones); below that the old
   two-line style keeps it clear of the edge. */
@media (min-width:360px) and (max-width:399.98px){.hire .header-employers{white-space:nowrap;max-width:none;text-align:left;line-height:1;font-size:min(.875rem,3.7vw)}}
/* Demo section layout (Steven, 9 Nov): both windows first, then the one line inviting an email. The second window
   reuses the first window's measurements exactly: the same Mac frame (52px title bar), the same column template as the
   inbox (11rem folders + list | steps from 1200px, list | steps from 1024px) so its divider sits on the inbox's divider,
   and the same 24px inset on each side of it. Samples on the left, the form on the right, the AI's answer full width. */
.try-live:not([hidden]){margin-top:var(--s6)}
@media (min-width:1024px){
  .try-live:not([hidden]){display:grid;grid-template-columns:11rem minmax(0,1fr) minmax(0,1.05fr);grid-template-rows:auto auto 1fr auto;align-items:start}
  .try-live>h3,.try-live>.live-out{grid-column:1/-1}
  .try-live>.live-lead,.try-live>.live-picks{grid-column:1/3;margin-inline:var(--s5)}
  .try-live>.live-lead{grid-row:2;margin-top:var(--s5)}
  .try-live>.live-picks{grid-row:3;flex-direction:column;align-items:flex-start;margin-top:var(--s4)}
  /* The form pane: its left border is the inbox's divider line; its text starts 24px in, like the steps beside the inbox. */
  .try-live>.live-form{grid-column:3;grid-row:2/4;align-self:stretch;max-width:none;margin:0;padding:var(--s5) var(--s5) var(--s5) calc(var(--s5) - 1px);border-left:1px solid var(--rule)}
  .try-live>.live-form label:first-child{margin-top:0}
}
@media (min-width:1024px) and (max-width:1199.98px){.try-live:not([hidden]){grid-template-columns:minmax(0,1fr) minmax(0,1.05fr)}
  .try-live>.live-lead,.try-live>.live-picks{grid-column:1}.try-live>.live-form{grid-column:2}}
.try-next{margin-top:var(--s5)}
/* Second window refined (Steven, 9 Nov: "same font sizes as the first window; the answer as a dialog"). Every size is
   copied from the first window: lead and labels 15px like the subjects and step rules, inputs 15px, the samples as a
   Mail-style source list (15px/600 rows like the folders), the button as the title bar's macOS push button (34px tall,
   15px/600). The AI's answer opens as the same centred macOS alert as "Inbox sorted", over a dim layer in the window. */
.try-live:not([hidden]){position:relative}
.try-live>.live-lead{font:400 .9375rem/1.45 var(--f-sans);color:var(--ink-soft);max-width:none}
.try-live .live-picks{gap:2px}
.try-live .live-pick{min-height:44px;width:100%;padding:0 12px;border:0;border-radius:6px;background:none;text-align:left;font:600 .9375rem/1.3 var(--f-sans);color:#1d1d1f}
.try-live .live-pick[aria-pressed="true"]{background:#0a6ae01f;color:#1d1d1f;border:0}
@media (hover:hover) and (pointer:fine){.try-live .live-pick:not([aria-pressed="true"]):hover{background:#0a1f3d0a}}
.try-live .live-form label{font:600 .9375rem/1.3 var(--f-sans);color:#1d1d1f;margin-top:var(--s3)}
.try-live .live-form input,.try-live .live-form textarea{min-height:44px;padding:10px 12px;border:1px solid #d6d6dc;border-radius:7px;font:400 .9375rem/1.45 var(--f-sans);box-shadow:inset 0 1px 1px #0a1f3d0a}
.try-live .live-form input:focus-visible,.try-live .live-form textarea:focus-visible{outline:3px solid var(--blue);outline-offset:1px;border-color:#0a6ae0}
.try-live .live-go{margin-top:var(--s4);gap:var(--s2) var(--s4)}
.try-live .live-go .button{min-height:44px;padding:0 18px;border:0;border-radius:7px;background:var(--mac-blue);color:#fff;font:600 .9375rem/1 var(--f-sans);box-shadow:0 1px 2px #0a1f3d33}
@media (hover:hover) and (pointer:fine){.try-live .live-go .button:hover{background:var(--mac-blue-hover)}}
.try-live .live-go .button:active{background:var(--mac-blue-down)}
.try-live .live-note{font:400 .8125rem/1.45 var(--f-sans);color:#6e6e73}
/* The answer: a centred macOS alert in the window (the same box as "Inbox sorted"). */
.try-live>.live-out:not(:empty){position:absolute;inset:52px 0 0;z-index:5;display:grid;place-items:center;margin:0;padding:16px;border:0;border-radius:0 0 12px 12px;background:#1d1d1f33;overflow:auto}
.try-live .live-out>*{width:min(30rem,100%);max-width:none;margin:0;padding:22px 22px 16px;border:0;border-radius:12px;background:#f6f6f6;box-shadow:0 0 0 .5px #0000002e,0 24px 48px -12px #0a1f3d73}
.try-live .live-card.is-held{box-shadow:0 0 0 .5px #0000002e,inset 0 3px 0 var(--alert),0 24px 48px -12px #0a1f3d73}
.try-live .live-k{font:600 .75rem/1.3 var(--f-sans);letter-spacing:.08em;color:#6e6e73}
.try-live .live-v{margin-top:2px;font:400 .9375rem/1.45 var(--f-sans);color:#1d1d1f}
.try-live .live-plain{font-weight:600}
.try-live .live-card.is-held .live-plain{color:#8a1a12}
.try-live .live-model{font-size:.8125rem;color:#6e6e73}
.try-live .live-card .button,.try-live .live-draft .button,.try-live .live-close{min-height:40px;padding:0 16px;border:0;border-radius:8px;font:600 .9375rem/1 var(--f-sans)}
.try-live .live-card>.button,.try-live .live-draft>.button{background:var(--mac-blue);color:#fff}
.try-live .live-close{justify-self:end;background:#e9e9ed;color:#1d1d1f;box-shadow:inset 0 0 0 .5px #0000001f;cursor:pointer}
.try-live .live-draft{padding:12px;border-left:2px solid #0a6ae0;border-radius:6px;background:#fff}
.try-live .live-msg{font:400 .9375rem/1.45 var(--f-sans);color:#1d1d1f}
@media (prefers-reduced-motion:no-preference){.try-live>.live-out:not(:empty){animation:mac-dim .2s ease-out}.try-live .live-out>*{animation:mac-drop .28s cubic-bezier(.2,.8,.25,1)}}
@media print{.try-live>.live-out{position:static;background:none}}
@media (forced-colors:active){.try-live .live-out>*{border:1px solid CanvasText}}
/* Alert fit: the stamp sits on the rule's line, the two buttons share the last row (the dialog's own row, like "OK"),
   steps are 8px apart, and the window is never shorter than its dialog. */
.try-live .live-card{gap:8px;padding:18px 20px 14px}
.try-live .live-card .live-rule{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:2px 12px}
.try-live .live-card .live-rule .live-k{grid-column:1/-1}
.try-live .live-card .live-rule .stamp{grid-column:2;grid-row:2;margin:0;align-self:center}
.try-live .live-card>.button,.try-live .live-card>.live-close{grid-row:auto}
.try-live .live-card{grid-template-columns:minmax(0,1fr) auto}
.try-live .live-card>*{grid-column:1/-1}
.try-live .live-card>.button{grid-column:1;justify-self:start}
.try-live .live-card>.live-close{grid-column:2;justify-self:end}
.try-live .live-card>.live-model{order:9}
.try-live .live-draft-text{margin:4px 0 12px;font:400 .9375rem/1.45 var(--f-sans);color:#1d1d1f}
.try-live .live-draft .live-k{color:#6e6e73}
.try-live .live-pick:focus-visible,.try-live .live-close:focus-visible,.try-live .live-card .button:focus-visible{outline:3px solid var(--blue);outline-offset:2px}
/* Refine loop r1 (9 Nov): on phones the second window's title sits 12px after the traffic lights, left-aligned, exactly
   like the first window's (it was pushed to the right edge); its push button runs full width like "Sort my inbox". */
@media (max-width:760.98px){
  .try-live>h3{text-align:left;padding-left:calc(14px + 52px + 12px)}
  .try-live .live-go .button{width:100%}
}
/* r1b: the samples' text sits on the content line (their 12px hover padding hangs outside it, like Mail's source list),
   and the space between blocks follows one step: 16px lead→samples, 24px samples→form (was 72px on phones). */
@media (min-width:1024px){.try-live>.live-picks{margin-inline:calc(var(--s5) - 12px) var(--s5)}}
@media (max-width:1023.98px){.try-live>.live-form{margin-top:var(--s5)}.try-live>.live-form label:first-child{margin-top:0}}
.try-live>h3{text-wrap:balance}
/* r1c: first lines start at the inbox's depth: the first email's name sits 14px under the title bar, so the lead and the
   "From" label do too (lead text box 1.45 line height, label 1.3: offsets differ by the half-leading). */
@media (min-width:1024px){
  .try-live>.live-lead{margin-top:calc(var(--s4) - 3px)}
  .try-live>.live-form{padding-top:calc(var(--s4) - 2px)}
}
/* r2 (9 Nov): below 1024px the three samples sit in one wrapping row (stacked, each took a 44px row with a 48px gap).
   In the dialog, Close matches the "Inbox sorted" OK button (40px, 8px radius, 16px/600) and shares the last row with
   the action button; the note about the free AI sits under them in the alert's quiet grey. */
@media (max-width:1023.98px){.try-live .live-picks{flex-direction:row;flex-wrap:wrap;gap:4px 8px}.try-live .live-pick{width:auto;padding:0 12px}}
.try-live .live-close,.try-live .live-card>.button{min-height:40px;font:600 1rem/1 var(--f-sans);border-radius:8px}
.try-live .live-card>.live-close{min-width:96px}
/* r2b: below 1024px the samples are soft grey chips (8px radius, the inbox's #f5f5f7 sidebar grey) so they read as
   things to tap; the picked one takes the inbox's selected-folder tint. */
@media (max-width:1023.98px){.try-live .live-pick{background:#f0f0f3;border-radius:8px}.try-live .live-pick[aria-pressed="true"]{background:#0a6ae01f}
  .try-live .live-picks{margin-inline-start:var(--s5)}}
@media (max-width:599.98px){.try-live .live-picks{margin-inline-start:var(--s4)}}
/* 9 Nov (Steven): the dialog conforms to its window, like a real app window. The overlay covers the window's body
   (under the title bar, on every screen size), the window never grows, and a long answer scrolls inside the dialog. */
.try-live>.live-out:not(:empty){inset:var(--bar,52px) 0 0;display:flex;align-items:center;justify-content:center;border-radius:0 0 12px 12px;overflow:hidden}
.try-live .live-out>*{max-height:100%;overflow:auto;overscroll-behavior:contain;align-self:var(--alert-align,center)}
/* The answer layer is never part of the window's layout: empty it takes no space, open it covers the body. So the
   window is the same size before, during and after a dialog, at every width. */
.try-live>.live-out:empty{display:none}
.try-live>.live-out{margin:0}
.try-live .live-out>*{max-height:min(100%,var(--vis-h,100%))}
/* Neville's words (9 Nov 2026: he agreed verbally to be quoted; Steven confirmed the wording and asked for it to sit in
   the Well Done Cleaning Services tile on the hire page only). A quiet quote under the work line. */
.tiles .tile-quote{display:block;margin-top:var(--s4);padding-left:var(--s3);border-left:2px solid var(--rule);color:var(--ink);font-style:italic;text-indent:-.4em}
.tiles .tile-cite{display:block;margin-top:var(--s1);padding-left:var(--s3);font-size:var(--t-sm)}
/* 9 Nov 2026 (Steven): 'What I work with.' grouped like the CV skills; the group names in the ink colour, inline. */
.tiles .tile-k{display:inline;font-weight:600;color:var(--ink)}

/* Audit fixes, 9 Nov 2026 (line-by-line code audit; each verified in a headless browser). */
/* CSS-04: in forced colours every borderless button keeps a visible edge. */
@media (forced-colors:active){.mail-bar .demo-start,.mac-btn,.try-live .live-pick,.try-live .live-go .button,.live-close,.live-card>.button,.live-draft>.button{border:1px solid ButtonText}}
/* CSS-06: the "Allowed" stamp's text ends on the column edge, like "Held". */
.mail-ai .stamp-checked{padding-inline:0}
/* CSS-07: the live panel never prints (it is a form). */
@media print{.try-live,.try-live:not([hidden]){display:none!important}}
/* CSS-10: Safari has no CSS "d", so the zoom icon's vertical stroke is its own path, hidden when zoomed. */
.cv.is-zoomed .cv-zoom .zoom-v{display:none}
/* CSS-11: the one-column inbox has no right border on its list. */
@media (max-width:1023.98px){.mail-list{border-right:0}}
