/* Verity Detail Studio — demonstration site. System fonts only, zero external requests. */

:root{
  /* five steps of near-black — depth by value, not by hue */
  --n0:#050506;              /* the far corners of the room */
  --n1:#0a0a0b;              /* the field */
  --n2:#0f0f12;
  --n3:#151519;
  --n4:#1d1d22;              /* a surface standing in the light */
  --black:#0a0a0b;
  --black-2:#101012;
  --ink:#f2ede5;
  --mute:#8f8981;
  --mute-2:#6d6862;
  --line:#232326;
  --line-2:#2f2f33;
  --accent:#d8c6a0;          /* champagne — used almost nowhere */
  --accent-warm:#e6d5ae;     /* champagne, closer to the light */
  --lightbox:#7fa8cc;        /* the cold blue of a light box — used for almost nothing */
  --edge:rgba(242,237,229,.085);      /* a highlight along ONE edge */
  --edge-lit:rgba(242,237,229,.22);
  --glow:rgba(216,198,160,.05);
  --paper:#f7f3ec;
  --paper-ink:#16171a;
  --paper-mute:#5c5a55;
  --paper-line:#ded7cb;

  --display:"Didot","Bodoni 72","Bodoni MT","Hoefler Text",Garamond,"Times New Roman",Times,serif;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;

  --gut:clamp(1.25rem,5vw,4.5rem);
  --air:clamp(4rem,11vw,9.5rem);

  /* motion — slow, eased, nothing bounces */
  --t:220ms;
  --t-slow:300ms;
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-long:cubic-bezier(.16,.84,.34,1);
}

*,*::before,*::after{box-sizing:border-box}

html{ -webkit-text-size-adjust:100%; }

body{
  margin:0;
  background:var(--black);
  background-image:
    radial-gradient(120% 70% at 50% -12%, #1d1d21 0%, #121214 38%, var(--black) 72%);
  background-attachment:fixed;
  color:var(--ink);
  font-family:var(--sans);
  font-size:1.0625rem;
  line-height:1.75;
  letter-spacing:.005em;
  overflow-x:hidden;
}

img,svg{max-width:100%;height:auto}

a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--line-2);padding-bottom:.08em}
a:hover{border-bottom-color:var(--accent);color:#fff}
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:2px solid var(--accent);outline-offset:3px;border-radius:2px
}

/* ---------- demonstration strip ---------- */
.demostrip{
  display:flex;gap:.7rem;align-items:flex-start;
  padding:.7rem var(--gut);
  background:#131215;
  border-bottom:1px solid var(--line);
  font-size:.8125rem;line-height:1.5;color:var(--mute);
  font-family:var(--sans);
}
.demostrip b{color:var(--ink);font-weight:600}
.demostrip a{color:var(--accent);border-bottom-color:rgba(216,198,160,.35);white-space:nowrap}
.demostrip__dot{
  flex:0 0 auto;width:.5rem;height:.5rem;margin-top:.5rem;border-radius:50%;
  background:var(--accent);box-shadow:0 0 0 4px rgba(216,198,160,.09)
}

/* ---------- shell ---------- */
.wrap{width:100%;max-width:78rem;margin:0 auto;padding:0 var(--gut)}
.narrow{max-width:44rem}
.mid{max-width:58rem}

header.site{padding:clamp(1.5rem,4vw,2.75rem) 0 clamp(1.25rem,3vw,2rem)}
.brandline{display:flex;flex-wrap:wrap;align-items:baseline;gap:.75rem 1.5rem;justify-content:space-between}
.brand{
  font-family:var(--display);font-size:clamp(1.2rem,2.4vw,1.5rem);
  letter-spacing:.06em;text-transform:uppercase;border:0;line-height:1.2
}
.brand:hover{color:#fff}
.brand span{color:var(--mute);letter-spacing:.34em;font-size:.55em;display:block;text-transform:uppercase;font-family:var(--sans);margin-top:.35rem}
.brandmeta{font-family:var(--mono);font-size:.75rem;letter-spacing:.1em;color:var(--mute);text-transform:uppercase}
.brandmeta a{border:0;color:var(--mute)}
.brandmeta a:hover{color:var(--accent)}

nav.site{margin-top:clamp(1.25rem,3vw,2rem);border-top:1px solid var(--line);padding-top:.85rem}
nav.site ul{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:.35rem 1.4rem}
nav.site a{
  border:0;font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mute);display:inline-block;padding:.3rem 0
}
nav.site a:hover{color:var(--ink)}
nav.site a[aria-current="page"]{color:var(--accent)}

main{display:block}
section{padding-block:var(--air)}
section+section{padding-top:0}
.hero+section,
.showcase+section{padding-top:var(--air)}
.rule{height:1px;background:var(--line);border:0;margin:0}

/* ---------- type ---------- */
h1,h2,h3{font-family:var(--display);font-weight:400;letter-spacing:-.01em;text-wrap:balance}
h1{font-size:clamp(2.6rem,8vw,5.75rem);line-height:.98;margin:0 0 1.5rem}
h2{font-size:clamp(1.9rem,4.6vw,3.25rem);line-height:1.06;margin:0 0 1.25rem}
h3{font-size:clamp(1.25rem,2.6vw,1.7rem);line-height:1.2;margin:0 0 .6rem}
p{margin:0 0 1.35rem;max-width:40rem}
.lede{font-size:clamp(1.125rem,2vw,1.375rem);line-height:1.6;color:#e6e0d6;max-width:38rem}
.eyebrow{
  font-family:var(--mono);font-size:.72rem;letter-spacing:.24em;text-transform:uppercase;
  color:var(--mute);margin:0 0 1.5rem
}
.eyebrow--accent{color:var(--accent)}
.dim{color:var(--mute)}
.small{font-size:.9375rem;line-height:1.65}
strong,b{font-weight:600;color:#fff}

ul.plain{list-style:none;padding:0;margin:0 0 1.5rem;max-width:40rem}
ul.plain li{padding:.55rem 0 .55rem 1.4rem;position:relative;border-bottom:1px solid var(--line)}
ul.plain li::before{content:"";position:absolute;left:0;top:1.25rem;width:.45rem;height:1px;background:var(--mute-2)}

/* ---------- hero ---------- */
.hero,
.showcase{padding-top:clamp(1.5rem,4vw,3rem);padding-bottom:0}
.hero h1{max-width:16ch}
.hero__art{display:block;width:100%;margin:clamp(1.5rem,5vw,3.5rem) 0 0}
.hero__cap{
  font-family:var(--mono);font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--mute-2);margin:1rem 0 0;max-width:52rem
}

/* ---------- the report (the one bright object) ---------- */
.report{
  background:var(--paper);color:var(--paper-ink);
  padding:clamp(1.5rem,4.5vw,3.25rem);
  box-shadow:0 0 0 1px rgba(255,255,255,.05), 0 3rem 6rem -2rem rgba(0,0,0,.9), 0 0 9rem rgba(216,198,160,.05);
  max-width:60rem;margin:0 auto
}
.report a{color:var(--paper-ink);border-bottom-color:var(--paper-line)}
.report p{color:#2a2b2f;max-width:46rem}
.report strong,.report b{color:var(--paper-ink)}
.report__head{display:flex;flex-wrap:wrap;gap:1rem 2.5rem;justify-content:space-between;align-items:flex-start;
  border-bottom:1px solid var(--paper-line);padding-bottom:1.25rem;margin-bottom:1.75rem}
.report__title{font-family:var(--display);font-size:clamp(1.5rem,3.4vw,2.15rem);line-height:1.05;margin:0}
.report__meta{font-family:var(--mono);font-size:.72rem;line-height:1.9;letter-spacing:.06em;color:var(--paper-mute);text-transform:uppercase;text-align:left}
.report h4{font-family:var(--mono);font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;color:var(--paper-mute);
  margin:2.25rem 0 1rem;font-weight:600}
.report h4:first-of-type{margin-top:0}

.plan{display:block;width:100%;max-width:44rem;margin:0 auto}

.readings{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:1.25rem 0 0;padding-bottom:.5rem}
.readings ol{display:flex;flex-wrap:wrap;list-style:none;margin:0;padding:0;gap:0}
.readings li{
  flex:0 0 auto;min-width:7.25rem;padding:.55rem 1rem .55rem 0;margin-right:1rem;
  border-right:1px solid var(--paper-line);font-family:var(--mono);white-space:nowrap
}
.readings li:last-child{border-right:0;margin-right:0}
.readings .lbl{display:block;font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;color:var(--paper-mute)}
.readings .val{display:block;font-size:1.0625rem;margin-top:.2rem;color:var(--paper-ink)}
.readings li.flag .val{color:#8a6d16}
.readings li.flag .lbl{color:#8a6d16}
.readings li.flag .val::after{content:" \25C6";font-size:.62em;vertical-align:.3em}
.readings__note{font-family:var(--mono);font-size:.68rem;letter-spacing:.08em;color:var(--paper-mute);margin:.75rem 0 0;text-transform:uppercase}

.lines{width:100%;border-collapse:collapse;margin:0 0 1rem;font-size:.9375rem}
.lines th{
  text-align:left;font-family:var(--mono);font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--paper-mute);font-weight:600;padding:0 0 .6rem;border-bottom:1px solid var(--paper-line)
}
.lines th:last-child,.lines td:last-child{text-align:right;white-space:nowrap}
.lines td{padding:.85rem 0;border-bottom:1px solid var(--paper-line);vertical-align:top}
.lines td:first-child{padding-right:1.25rem}
.lines .amt{font-family:var(--mono);font-size:.9375rem}
.lines tr.total td{border-bottom:0;padding-top:1.1rem;font-weight:600}
.lines tr.total .amt{font-size:1.0625rem}

.declined{background:#efe7d5;box-shadow:inset 3px 0 0 #b08d2b}
.declined td{border-bottom-color:#e0d5bb}
.declined td:first-child{padding-left:1rem}
.declined .tag{
  display:inline-block;font-family:var(--mono);font-size:.62rem;letter-spacing:.18em;text-transform:uppercase;
  color:#7a5f10;border:1px solid #cbb376;padding:.15rem .5rem;margin-bottom:.5rem
}
.declined .amt{color:#7a5f10}
.declined p{margin:.6rem 0 0;font-size:.9375rem;line-height:1.65;color:#3a3b3e;max-width:44rem}

.reportnote{
  font-family:var(--mono);font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--paper-mute);border-top:1px solid var(--paper-line);padding-top:1.1rem;margin:1.5rem 0 0;line-height:1.9
}

/* ---------- the ladder (services, process) — no cards ---------- */
.ladder{border-top:1px solid var(--line);margin:clamp(2rem,5vw,3.5rem) 0 0;counter-reset:rung}
.rung{
  display:grid;grid-template-columns:6.5rem 1fr;gap:0 clamp(1.25rem,4vw,3.5rem);
  padding:clamp(2rem,4.5vw,3.25rem) 0;border-bottom:1px solid var(--line);position:relative
}
.rung__n{
  font-family:var(--mono);font-size:.72rem;letter-spacing:.2em;color:var(--mute-2);
  padding-top:.6rem;text-transform:uppercase
}
.rung h3{margin-top:0}
.rung p:last-child{margin-bottom:0}
.rung__more{
  font-family:var(--mono);font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;
  border:0;color:var(--accent);display:inline-block;margin-top:.35rem
}
.rung__more:hover{color:#fff}
@media (max-width:640px){
  .rung{grid-template-columns:1fr;gap:.75rem}
  .rung__n{padding-top:0}
}

/* ---------- numbers we publish ---------- */
.figures{border-top:1px solid var(--line);margin-top:clamp(2rem,5vw,3.5rem)}
.figure{padding:clamp(2rem,4.5vw,3rem) 0;border-bottom:1px solid var(--line)}
.figure__n{
  font-family:var(--display);font-size:clamp(2.5rem,7vw,4.5rem);line-height:1;margin:0 0 .5rem;
  color:var(--ink)
}
.figure__n em{font-style:normal;font-family:var(--mono);font-size:.26em;letter-spacing:.12em;color:var(--mute);margin-left:.5rem;vertical-align:.55em}
.figure p{margin-bottom:0}

/* ---------- quiet blocks ---------- */
.note{
  border-left:1px solid var(--line-2);padding:.15rem 0 .15rem 1.5rem;margin:2rem 0;
  color:var(--mute);max-width:38rem
}
.note strong{color:var(--ink)}
.mark{color:var(--accent)}

.kv{margin:0;font-family:var(--mono);font-size:.85rem;line-height:1.9}
.kv div{display:flex;flex-wrap:wrap;gap:.25rem 1.5rem;padding:.6rem 0;border-bottom:1px solid var(--line)}
.kv dt{flex:0 0 11rem;font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;color:var(--mute)}
.kv dd{margin:0;flex:1 1 14rem;color:var(--ink)}

.empty{
  border:1px dashed var(--line-2);padding:clamp(2rem,7vw,5rem) clamp(1.25rem,4vw,3rem);
  text-align:center;color:var(--mute);max-width:52rem;margin:2.5rem 0
}
.empty__mark{font-family:var(--mono);font-size:.7rem;letter-spacing:.24em;text-transform:uppercase;color:var(--mute-2);margin:0 0 1rem}
.empty p{margin:0 auto;max-width:34rem}
.empty p+p{margin-top:1rem}

.faqitem{border-bottom:1px solid var(--line);padding:clamp(1.75rem,4vw,2.5rem) 0}
.faqitem h3{margin-bottom:.75rem}
.faqitem p:last-child{margin-bottom:0}

/* ---------- form ---------- */
form.request{max-width:38rem;margin-top:2.5rem}
.field{margin-bottom:1.75rem}
.field label{display:block;font-family:var(--mono);font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;color:var(--mute);margin-bottom:.5rem}
.field input,.field select,.field textarea{
  width:100%;background:transparent;border:0;border-bottom:1px solid var(--line-2);
  color:var(--ink);font-family:var(--sans);font-size:1rem;padding:.6rem 0;border-radius:0
}
.field select{ -webkit-appearance:none;appearance:none;background-image:none}
.field select option{background:#141416;color:var(--ink)}
.field textarea{min-height:7rem;resize:vertical}
.field input:hover,.field select:hover,.field textarea:hover{border-bottom-color:var(--mute-2)}
.btn{
  display:inline-block;background:transparent;border:1px solid var(--line-2);color:var(--ink);
  font-family:var(--mono);font-size:.72rem;letter-spacing:.18em;text-transform:uppercase;
  padding:.95rem 1.9rem;cursor:pointer;border-radius:0
}
.btn:hover{border-color:var(--accent);color:#fff}
.formnote{font-size:.875rem;color:var(--mute);max-width:38rem;margin-top:1.25rem}

/* ---------- footer ---------- */
footer.site{border-top:1px solid var(--line);margin-top:var(--air);padding:clamp(2.5rem,6vw,4.5rem) 0 clamp(2rem,5vw,3.5rem)}
.footcols{display:flex;flex-wrap:wrap;gap:2.5rem 4rem;margin-bottom:3rem}
.footcol{flex:1 1 13rem;min-width:0}
.footcol h4{font-family:var(--mono);font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:var(--mute-2);margin:0 0 1rem;font-weight:600}
.footcol ul{list-style:none;margin:0;padding:0}
.footcol li{margin-bottom:.55rem}
.footcol a{border:0;font-size:.9375rem;color:var(--mute)}
.footcol a:hover{color:var(--ink)}
.footcol p{font-size:.9375rem;color:var(--mute);margin:0 0 .5rem;max-width:20rem}
.footbase{border-top:1px solid var(--line);padding-top:1.75rem;font-size:.8125rem;color:var(--mute-2);line-height:1.7}
.footbase a{color:var(--mute-2);border-bottom-color:var(--line)}

/* ---------- chat launcher (bottom LEFT — host page owns bottom right) ---------- */
.chat{position:fixed;left:1rem;bottom:1rem;z-index:9999;font-family:var(--sans)}
.chat__btn{
  background:#141417;color:var(--ink);border:1px solid var(--line-2);
  font-family:var(--mono);font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;
  padding:.85rem 1.25rem;cursor:pointer;border-radius:0;
  box-shadow:0 1.5rem 3rem -1rem rgba(0,0,0,.8);display:flex;align-items:center;gap:.6rem
}
.chat__btn:hover{border-color:var(--accent)}
.chat__btn::before{content:"";width:.4rem;height:.4rem;border-radius:50%;background:var(--accent)}
.chat__panel[hidden]{display:none!important}
.chat__panel{
  width:min(21rem,calc(100vw - 2rem));background:#111113;border:1px solid var(--line-2);
  box-shadow:0 2rem 5rem -1rem rgba(0,0,0,.9);margin-bottom:.6rem;display:flex;flex-direction:column;
  max-height:min(30rem,calc(100vh - 6rem))
}
.chat__head{
  display:flex;justify-content:space-between;align-items:center;gap:1rem;
  padding:.85rem 1rem;border-bottom:1px solid var(--line);
  font-family:var(--mono);font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;color:var(--mute)
}
.chat__head button{background:none;border:0;color:var(--mute);font-size:1.15rem;line-height:1;cursor:pointer;padding:.15rem .35rem}
.chat__head button:hover{color:var(--ink)}
.chat__log{padding:1rem;overflow-y:auto;flex:1 1 auto}
.chat__log .m{margin:0 0 .75rem;font-size:.875rem;line-height:1.6;max-width:100%}
.chat__log .m--bot{color:var(--ink)}
.chat__log .m--you{color:var(--accent);font-family:var(--mono);font-size:.75rem;letter-spacing:.06em;text-align:right}
.chat__opts{padding:0 1rem 1rem;display:flex;flex-direction:column;gap:.4rem}
.chat__opts button{
  text-align:left;background:transparent;border:1px solid var(--line);color:var(--ink);
  font-family:var(--sans);font-size:.8125rem;padding:.6rem .75rem;cursor:pointer;border-radius:0;line-height:1.4
}
.chat__opts button:hover{border-color:var(--accent)}
.chat__opts input{
  width:100%;background:transparent;border:0;border-bottom:1px solid var(--line-2);color:var(--ink);
  font-family:var(--sans);font-size:.8125rem;padding:.5rem 0;border-radius:0
}
.chat__opts .chat__send{border:1px solid var(--line-2);text-align:center;font-family:var(--mono);font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;padding:.7rem}
@media (max-width:420px){ .chat{left:.6rem;bottom:.6rem} }

@media (prefers-reduced-motion:no-preference){
  .chat__panel{animation:rise .18s ease-out}
  @keyframes rise{from{opacity:0;transform:translateY(.4rem)}to{opacity:1;transform:none}}
}


/* =====================================================================
   LIGHT, MOTION, ILLUSTRATION
   A studio is black because the light does the work. Everything below
   is either a light source, a falloff, a surface catching one edge of
   it, or something moving slowly through it.
   ===================================================================== */

/* ---------- 1. the lighting model ---------- */

body{
  background-color:var(--n0);
  background-image:
    /* the champagne warms only where the light is strongest */
    radial-gradient(72% 40% at 50% -2%, rgba(216,198,160,.055) 0%, rgba(216,198,160,0) 64%),
    /* the pool itself, five steps of near-black falling away from it */
    radial-gradient(128% 74% at 50% -14%,
      var(--n4) 0%, var(--n3) 22%, var(--n2) 42%, var(--n1) 64%, var(--n0) 100%);
}

/* falloff toward the page edges — fixed, so the room stays still while you scroll */
body::after{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(130% 96% at 50% 26%, rgba(0,0,0,0) 38%, rgba(0,0,0,.34) 76%, rgba(0,0,0,.62) 100%);
}
.demostrip,header.site,main,footer.site{position:relative;z-index:1}

/* a single hairline of light under the masthead, brightest in the middle */
nav.site{
  border-top:0;
  background-image:linear-gradient(90deg,
    rgba(35,35,38,0) 0%, var(--line) 12%, var(--edge) 46%, var(--line) 78%, rgba(35,35,38,0) 100%);
  background-size:100% 1px;background-repeat:no-repeat;background-position:0 0;
}

/* the eyebrow gets a lit point — the smallest light source on the page */
.eyebrow{position:relative;padding-left:1.35rem}
.eyebrow::before{
  content:"";position:absolute;left:0;top:.62em;width:.3rem;height:.3rem;border-radius:50%;
  background:var(--mute-2);
}
.eyebrow--accent::before{
  background:var(--accent);box-shadow:0 0 0 3px rgba(216,198,160,.10), 0 0 12px 1px rgba(216,198,160,.45);
}

/* ---------- 2. type: bigger, more confident ---------- */
h1{font-size:clamp(2.75rem,8.6vw,6.5rem);letter-spacing:-.018em;overflow-wrap:break-word}
h2{font-size:clamp(2rem,4.9vw,3.6rem);letter-spacing:-.015em}
.hero h1{max-width:15ch}
.hero .lede{max-width:40rem}

/* ---------- 3. transitions — understated, 200–300ms ---------- */
a{transition:color var(--t) var(--ease), border-color var(--t) var(--ease)}
.brand,.brandmeta a,.footcol a,.rung__more{transition:color var(--t) var(--ease)}

nav.site a{position:relative;transition:color var(--t) var(--ease)}
nav.site a::after{
  content:"";position:absolute;left:0;right:0;bottom:.05rem;height:1px;background:var(--accent);
  transform:scaleX(0);transform-origin:left center;
  transition:transform var(--t-slow) var(--ease), opacity var(--t) var(--ease);opacity:.7
}
nav.site a:hover::after{transform:scaleX(1)}
nav.site a[aria-current="page"]::after{transform:scaleX(1);opacity:.35}

.btn{
  position:relative;overflow:hidden;
  transition:color var(--t) var(--ease), border-color var(--t) var(--ease),
             background-color var(--t-slow) var(--ease), box-shadow var(--t-slow) var(--ease);
}
.btn::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg, rgba(216,198,160,0) 36%, rgba(216,198,160,.16) 50%, rgba(216,198,160,0) 64%);
  transform:translateX(-120%);transition:transform 720ms var(--ease-long);
}
.btn:hover{
  background-color:rgba(216,198,160,.045);border-color:var(--accent);
  box-shadow:inset 0 1px 0 rgba(242,237,229,.10), 0 1.25rem 3rem -1.5rem rgba(216,198,160,.5);
}
.btn:hover::after{transform:translateX(120%)}

.field input,.field select,.field textarea{
  transition:border-color var(--t) var(--ease), background-color var(--t) var(--ease)
}
.field input:hover,.field select:hover,.field textarea:hover,
.field input:focus,.field select:focus,.field textarea:focus{
  background-color:rgba(242,237,229,.018)
}

.chat__btn,.chat__opts button{transition:border-color var(--t) var(--ease), background-color var(--t) var(--ease), color var(--t) var(--ease)}
.chat__btn:hover{background:#191a1e}
.chat__opts button:hover{background:rgba(216,198,160,.04)}

/* ---------- 4. the ladder — stages, lit one edge at a time ---------- */
.ladder{border-top-color:var(--line)}
.rung{
  transition:background-color var(--t-slow) var(--ease);
  background-image:linear-gradient(100deg, rgba(242,237,229,.02) 0%, rgba(242,237,229,0) 58%);
  background-size:100% 100%;background-repeat:no-repeat;
  opacity:1;
}
.rung::before{
  content:"";position:absolute;left:0;right:0;top:-1px;height:1px;pointer-events:none;
  background:linear-gradient(90deg, rgba(242,237,229,0) 0%, var(--edge-lit) 14%, var(--edge-lit) 52%, rgba(242,237,229,0) 88%);
  opacity:0;transition:opacity var(--t-slow) var(--ease)
}
.rung:hover::before,.rung:focus-within::before{opacity:1}
.rung:hover .rung__n,.rung:focus-within .rung__n{color:var(--accent)}
.rung:hover .stagemark,.rung:focus-within .stagemark{color:var(--accent-warm)}
.rung__more{position:relative}
.rung__more::after{
  content:"";position:absolute;left:0;right:1.1em;bottom:-.25rem;height:1px;background:currentColor;opacity:.45;
  transform:scaleX(0);transform-origin:left center;transition:transform var(--t-slow) var(--ease)
}
.rung__more:hover::after{transform:scaleX(1)}

/* the stage mark sits in the number column, above the label */
.stagemark{
  display:block;width:3.5rem;height:3.5rem;margin:0 0 .85rem;
  color:var(--mute);transition:color var(--t-slow) var(--ease);
  overflow:visible
}
.stagemark .s-line{fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.stagemark .s-thin{fill:none;stroke:currentColor;stroke-width:1;stroke-linecap:round;opacity:.6}
.stagemark .s-fill{fill:currentColor}
.stagemark .s-hot{fill:none;stroke:var(--accent);stroke-width:1.4;stroke-linecap:round}
@media (max-width:640px){ .stagemark{width:2.75rem;height:2.75rem;margin-bottom:.5rem} }

/* ---------- 5. the report — the one bright object in the room ---------- */
.report{
  position:relative;
  box-shadow:
    0 0 0 1px rgba(255,255,255,.06),
    0 3.5rem 7rem -2.5rem rgba(0,0,0,.95),
    0 0 12rem rgba(216,198,160,.09);
}
.report::before{
  content:"";position:absolute;left:0;right:0;top:0;height:2px;pointer-events:none;
  background:linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.85) 30%, rgba(255,255,255,.5) 70%, rgba(255,255,255,0));
}
.declined{transition:box-shadow var(--t-slow) var(--ease), background-color var(--t-slow) var(--ease)}
.declined:hover{background:#ece2cc;box-shadow:inset 4px 0 0 #a8831f}

/* ---------- 6. designed image slots — a frame waiting for a photograph ---------- */
.slot{margin:clamp(2.25rem,5vw,3.75rem) 0;max-width:62rem}
.slot__frame{
  position:relative;display:block;width:100%;aspect-ratio:16/10;min-height:11rem;overflow:hidden;
  background:radial-gradient(88% 128% at 50% 4%, var(--n4) 0%, var(--n2) 46%, var(--n0) 100%);
  border:1px solid var(--line);
  box-shadow:inset 0 1px 0 var(--edge), 0 2.5rem 5rem -3rem rgba(0,0,0,.9);
}
.slot__frame svg{position:absolute;inset:0;width:100%;height:100%;display:block;max-width:none}
.slot__tag{
  position:absolute;left:.9rem;top:.85rem;z-index:2;
  font-family:var(--mono);font-size:.58rem;letter-spacing:.24em;text-transform:uppercase;
  color:var(--mute-2);border:1px solid var(--line-2);padding:.22rem .55rem;
  background:rgba(5,5,6,.66)
}
.slot__cap{
  font-family:var(--mono);font-size:.68rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--mute-2);margin:.85rem 0 0;max-width:46rem;line-height:1.85
}
.slot__cap b{color:var(--mute);font-weight:600}
.slot .sl-line{fill:none;stroke:#f2ede5;stroke-opacity:.16;stroke-width:1.1;stroke-linecap:round;stroke-linejoin:round}
.slot .sl-faint{fill:none;stroke:#f2ede5;stroke-opacity:.07;stroke-width:1;stroke-linecap:round}
.slot .sl-warm{fill:none;stroke:#d8c6a0;stroke-opacity:.34;stroke-width:1.1;stroke-linecap:round}
@media (max-width:640px){ .slot__frame{aspect-ratio:4/3} }

/* ---------- 7. hand-drawn diagrams ---------- */
.diagram{margin:clamp(2.25rem,5vw,3.75rem) 0;max-width:62rem}
.diagram svg{display:block;width:100%;height:auto}
.diagram figcaption{
  font-family:var(--mono);font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--mute-2);margin:.95rem 0 0;max-width:48rem;line-height:1.85
}
.diagram figcaption b{color:var(--mute);font-weight:600}
.dg-stroke{fill:none;stroke:#f2ede5;stroke-opacity:.22;stroke-width:1.1}
.dg-thin{fill:none;stroke:#f2ede5;stroke-opacity:.12;stroke-width:1}
.dg-warm{fill:none;stroke:var(--accent);stroke-opacity:.75;stroke-width:1.4}
.dg-cool{fill:none;stroke:var(--lightbox);stroke-opacity:.5;stroke-width:1.1}
.dg-label{font-family:var(--mono);font-size:.8125rem;letter-spacing:.14em;fill:#8f8981;text-transform:uppercase}
.dg-label--warm{fill:var(--accent)}
.dg-label--cool{fill:var(--lightbox)}
.dg-num{font-family:var(--mono);font-size:.8125rem;letter-spacing:.08em;fill:#f2ede5}
/* the SVG scales with its container, so the label must grow as the container shrinks */
@media (max-width:1000px){ .dg-label{font-size:.9375rem} .dg-num{font-size:1rem} }
@media (max-width:660px){ .dg-label{font-size:1.375rem} .dg-num{font-size:1.5rem} }

/* ---------- 8. the hero plate on the inner pages ---------- */
.heroplate{
  position:relative;display:flex;flex-wrap:wrap;align-items:center;
  gap:clamp(1.25rem,4vw,2.75rem);
  margin:clamp(2rem,5vw,3.25rem) 0 0;
  padding:clamp(1.75rem,4.5vw,2.75rem) 0 clamp(1.75rem,4.5vw,2.75rem);
  border-top:1px solid var(--line);
}
.heroplate::before{
  content:"";position:absolute;left:0;right:0;top:-1px;height:1px;pointer-events:none;
  background:linear-gradient(90deg, var(--edge-lit) 0%, rgba(242,237,229,.06) 42%, rgba(242,237,229,0) 78%);
}
.heroplate::after{
  content:"";position:absolute;left:-8%;right:30%;top:-30%;bottom:-30%;pointer-events:none;z-index:-1;
  background:radial-gradient(48% 50% at 22% 50%, rgba(216,198,160,.07) 0%, rgba(216,198,160,0) 70%);
}
.heromark{
  flex:0 0 auto;width:clamp(4.5rem,14vw,6.5rem);height:clamp(4.5rem,14vw,6.5rem);
  color:var(--accent);overflow:visible
}
.heromark .m-line{fill:none;stroke:currentColor;stroke-opacity:.78;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round}
.heromark .m-thin{fill:none;stroke:#f2ede5;stroke-opacity:.22;stroke-width:1;stroke-linecap:round;stroke-linejoin:round}
.heromark .m-fill{fill:currentColor;fill-opacity:.8}
.heroplate__txt{flex:1 1 18rem;min-width:0}
.heroplate__txt p{margin:0;max-width:34rem}
.heroplate__k{
  font-family:var(--mono);font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--mute-2);margin:0 0 .55rem
}
.heroplate__v{font-size:1.0625rem;line-height:1.7;color:#e6e0d6}

/* ---------- 9. quiet blocks, lit one edge ---------- */
.note{
  border-left:0;position:relative;
  background:linear-gradient(100deg, rgba(242,237,229,.022), rgba(242,237,229,0) 62%);
  padding:.9rem 1.25rem .9rem 1.5rem;
}
.note::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:1px;
  background:linear-gradient(180deg, var(--edge-lit), var(--line-2) 46%, rgba(35,35,38,0));
}
.figure{transition:background-color var(--t-slow) var(--ease)}
.figure__n{
  background:linear-gradient(180deg, #fbf7ef 0%, var(--ink) 44%, #b9b3a9 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
@supports not (background-clip:text){ .figure__n{color:var(--ink)} }
.faqitem{transition:background-color var(--t-slow) var(--ease)}
.empty{
  border:1px solid var(--line);border-style:solid;
  background:radial-gradient(70% 100% at 50% 0%, rgba(242,237,229,.03), rgba(242,237,229,0) 72%);
  position:relative
}
.empty::before{
  content:"";position:absolute;left:0;right:0;top:-1px;height:1px;
  background:linear-gradient(90deg, rgba(242,237,229,0), var(--edge), rgba(242,237,229,0))
}

/* ---------- 10. motion. slow and expensive. nothing bounces. ---------- */
@media (prefers-reduced-motion:no-preference){

  /* the highlight sweeping across the paint, the way a light moves in a studio */
  .sheen{
    transform-box:view-box;transform-origin:0 0;
    animation:sheenpass 13s cubic-bezier(.42,0,.58,1) infinite;
  }
  .sheen--2{animation-duration:19s;animation-delay:-6s;opacity:.55}
  @keyframes sheenpass{
    0%   {transform:translateX(-520px)}
    62%  {transform:translateX(1300px)}
    100% {transform:translateX(1300px)}
  }

  /* the shoulder line catches it a beat later */
  .glint{
    stroke-dasharray:150 1200;
    animation:glintrun 13s cubic-bezier(.42,0,.58,1) infinite;
  }
  @keyframes glintrun{
    0%{stroke-dashoffset:1350;opacity:0}
    12%{opacity:.9}
    58%{stroke-dashoffset:-150;opacity:.9}
    70%,100%{stroke-dashoffset:-150;opacity:0}
  }

  /* the soft box breathes very slightly */
  .softbox{animation:breathe 11s ease-in-out infinite}
  @keyframes breathe{0%,100%{opacity:.72}50%{opacity:1}}

  /* a slow drift over the pool of light behind the hero */
  .hero__art{will-change:auto}

  /* section reveals — long, eased, and driven entirely by CSS.
     The DEFAULT state is visible: with no scroll-timeline support the
     @supports block never applies and every element renders normally.
     Nothing is ever hidden by script. */
  @keyframes lift{
    0%   {opacity:0;transform:translate3d(0,1.5rem,0)}
    58%  {opacity:1;transform:none}
    100% {opacity:1;transform:none}
  }
  @keyframes liftfast{
    0%   {opacity:0;transform:translate3d(0,1rem,0)}
    70%  {opacity:1;transform:none}
    100% {opacity:1;transform:none}
  }
  @supports (animation-timeline:view()){
    /* cover 0% is the instant the element first touches the bottom of the
       viewport, so nothing on screen is ever before the range start, and
       fill-mode:both holds the finished (visible) state afterwards. */
    section h2,
    section > .wrap > .lede,
    .rung,.figure,.faqitem,.slot,.diagram,.note,.empty,.kv,
    .heroplate,form.request,.lines,.plan{
      animation-name:lift;
      animation-duration:1s;
      animation-fill-mode:both;
      animation-timing-function:var(--ease-long);
      animation-timeline:view();
      animation-range:cover 0% cover 30%;
    }
    ul.plain li,.footcol{
      animation-name:liftfast;
      animation-duration:1s;
      animation-fill-mode:both;
      animation-timing-function:var(--ease-long);
      animation-timeline:view();
      animation-range:cover 0% cover 24%;
    }

    /* the report warms as it comes into the light. BOTH ends fully visible. */
    .report{
      animation-name:warmup;
      animation-duration:1s;
      animation-fill-mode:both;
      animation-timing-function:linear;
      animation-timeline:view();
      animation-range:cover 0% cover 36%;
    }
    @keyframes warmup{
      from{box-shadow:0 0 0 1px rgba(255,255,255,.035), 0 2rem 4rem -2.5rem rgba(0,0,0,.95), 0 0 3rem rgba(216,198,160,.008)}
      to  {box-shadow:0 0 0 1px rgba(255,255,255,.06), 0 3.5rem 7rem -2.5rem rgba(0,0,0,.95), 0 0 12rem rgba(216,198,160,.11)}
    }
  }

  /* The hero is on screen the moment the page loads, so it arrives on the
     document timeline instead. The cascade is built into the KEYFRAMES, not
     into animation-delay, and fill-mode stays `none`: outside the active
     phase the element's own visible style applies. If the animation never
     runs at all — reduced motion, a stalled timeline, anything — every word
     is still on screen. No script is involved anywhere. */
  @keyframes lift-1{0%{opacity:0;transform:translate3d(0,1.5rem,0)} 42%,100%{opacity:1;transform:none}}
  @keyframes lift-2{0%,10%{opacity:0;transform:translate3d(0,1.5rem,0)} 56%,100%{opacity:1;transform:none}}
  @keyframes lift-3{0%,18%{opacity:0;transform:translate3d(0,1.6rem,0)} 68%,100%{opacity:1;transform:none}}
  @keyframes lift-4{0%,26%{opacity:0;transform:translate3d(0,1.8rem,0)} 82%,100%{opacity:1;transform:none}}
  .hero .eyebrow,.hero h1,.hero > .wrap > .lede,.hero__art,.hero__cap,.hero .heroplate{
    animation-duration:1600ms;
    animation-delay:0s;
    animation-fill-mode:none;
    animation-timing-function:var(--ease-long);
    animation-timeline:auto;
    animation-range:normal;
    animation-iteration-count:1;
  }
  .hero .eyebrow{animation-name:lift-1}
  .hero h1{animation-name:lift-1}
  .hero > .wrap > .lede{animation-name:lift-2}
  .hero .heroplate{animation-name:lift-3}
  .hero__art{animation-name:lift-3;animation-duration:2000ms}
  .hero__cap{animation-name:lift-4;animation-duration:2000ms}
}

/* ---------- 11. reduced motion: everything holds still ---------- */
@media (prefers-reduced-motion:reduce){
  .sheen,.sheen--2,.glint,.softbox{animation:none!important}
  .glint{stroke-dasharray:none;opacity:.75}
  .btn::after{display:none}
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;
  }
}


/* ═══ 📱 MOBILE MENU — added 8 Sep 2026. See tools/navfix notes.
   ⛔ Do not give this a colour. The panel IS this site's own <nav>, so it
   keeps this site's own paper and rules; the button rides on currentColor.
   ⛔ Do not raise the breakpoint without re-measuring — 860 is where these
   nav rows start wrapping, which is the thing being fixed. */
.navbtn { display: none; }
.navq { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
        overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
@media (max-width: 860px) {
  .navbtn {
    display: inline-flex; align-items: center; gap: .55rem;
    padding: .5rem .8rem; border-radius: .5rem; cursor: pointer;
    font: inherit; font-size: .82rem; letter-spacing: .06em; text-transform: uppercase;
    color: currentColor;
    border: 1px solid currentColor;
    background: transparent;
    opacity: .85;
  }
  .navbtn__ico { position: relative; width: 15px; height: 2px; background: currentColor; }
  .navbtn__ico::before, .navbtn__ico::after {
    content: ""; position: absolute; left: 0; width: 15px; height: 2px; background: currentColor;
  }
  .navbtn__ico::before { top: -5px; }
  .navbtn__ico::after  { top:  5px; }
  .navq:focus-visible + .navbtn { outline: 2px solid currentColor; outline-offset: 2px; }

  /* the demo's own nav, closed */
  nav[aria-label="Main"], nav[aria-label="Primary"] { display: none; }
  .navq:checked ~ nav[aria-label="Main"],
  .navq:checked ~ nav[aria-label="Primary"] { display: block; width: 100%; }

  /* ⚠️ the lists inside are flex rows on every one of these sites; they have to
     stack, and the row gap has to become a tap target. */
  nav[aria-label="Main"] ul, nav[aria-label="Primary"] ul {
    display: block; margin: 0; padding: 0; list-style: none;
  }
  nav[aria-label="Main"] li, nav[aria-label="Primary"] li { display: block; }
  nav[aria-label="Main"] li a, nav[aria-label="Primary"] li a,
  nav[aria-label="Main"] > a, nav[aria-label="Primary"] > a {
    display: block; padding: .7rem .2rem; line-height: 1.2;
  }
  nav[aria-label="Main"] li + li, nav[aria-label="Primary"] li + li {
    border-top: 1px solid currentColor;
  }
  nav[aria-label="Main"] li + li, nav[aria-label="Primary"] li + li { border-top-color: color-mix(in srgb, currentColor 18%, transparent); }
}


/* ═══ 🔤 NAV TYPE PASS 9 Sep 2026 — size and tracking only.
   ⛔ Do not add colour, family, case or weight here: those are what keep these
   twelve sites from converging, and converging is the thing that was fixed
   once already. Measured before: 11–12.5px with tracking wide enough that
   the label read as separate letters rather than a word. */
nav[aria-label="Main"] a,
nav[aria-label="Primary"] a {
  font-size: .8125rem;
  letter-spacing: .1em;
}

/* ═══ 🖼️ THE HERO ART BELONGS IN THE FIRST SCREEN — 9 Sep 2026.
   Owner: "the demo heros need work too".
   🔴 MEASURED AT 1440x900: this hero's illustration began at y=868, so exactly
   32px of a 515px drawing was above the fold. The whole first screen was a
   104px headline and a paragraph — a wall of type, which is the same defect
   the botsonstaff home page had the same day.
   ⭐ THE ART WAS ALREADY IN THE HERO; nothing moved and nothing was drawn. The
   headline simply took the entire screen. It comes down, the gap above the
   drawing tightens, and the drawing is capped so a 2.1:1 panorama cannot eat a
   whole viewport on its own.
   ⛔ NOT a two-column hero — this illustration is 1200x560 and in a 46% column
   it would be a postage stamp. tree-service and garage-door go side-by-side
   because THEIR art is portrait-ish; this one is cinematic and stays full
   width. Twelve demos, twelve layouts: that is the point. */
@media (min-width: 900px) {
  .hero h1 { font-size: clamp(2.6rem, 5.2vw, 4rem); margin-bottom: 1.1rem; }
  .hero__art { margin-top: clamp(1rem, 2.2vw, 1.6rem); max-height: 46vh; }
  .hero > .wrap > .lede { margin-bottom: .4rem; }
}

/* ══════════════════════════════════════════════════════════════════════════
   ⭐ THE PROFESSIONAL PASS — auto detailing, 11 Sep 2026.
   The five gaps the roofing demo had, answered in this site's own materials.
   ⚠️ WHY A NEW TOKEN AND NOT A REPOINTED `--accent`. Champagne is wired into
   this site as a MATERIAL, not as a brand colour: `.dg-warm`, `--accent-warm`,
   the stage marks and the report glow all mean "warm light on paint". Point
   `--accent` at cyan and every one of those drawings turns cold while the
   token next to it is still called `-warm`. So clearcoat cyan is added as the
   one DECISIVE accent — mark, one headline phrase, the offer strip, the
   primary button and the nav's current page — and champagne stays what it
   already was: low-opacity trim inside the drawings.
   ⛔ No photograph. The car is a drawing and stays one.
   ══════════════════════════════════════════════════════════════════════════ */
:root{
  --clearcoat:#7FD4E8;        /* the one decisive accent */
  --clearcoat-hi:#A6E4F3;     /* hover */
  --clearcoat-ink:#04161B;    /* type that sits ON the accent */
  --clearcoat-wash:rgba(127,212,232,.08);
}

/* ── the mark ─────────────────────────────────────────────────────────── */
/* A water bead standing on a curved panel. The brand anchor was a bare text
   node plus a sub-line span, so the name is wrapped to make the row a clean
   two-item flex — and `.brand .brand__tx` restates everything `.brand span`
   sets, or the name would inherit the sub-line's mute and .34em tracking. */
.brand{ display:flex; align-items:center; gap:.75rem }
.brand .brand__tx{
  display:block; color:inherit; font-family:var(--display); font-size:1em;
  letter-spacing:.06em; text-transform:uppercase; margin-top:0; line-height:1.2;
}
.brandmark{
  width:30px; height:30px; flex:0 0 auto; color:var(--clearcoat);
  transition:transform var(--t) var(--ease), color var(--t) var(--ease);
}
.brand:hover .brandmark{ transform:translateY(-1px); color:var(--clearcoat-hi) }

/* the header reads in ONE accent, so the current page follows the mark */
nav.site a[aria-current="page"]{ color:var(--clearcoat) }
nav.site a::after{ background:var(--clearcoat) }

/* ── the headline carries the colour ──────────────────────────────────── */
h1 .hl{ font-style:normal; color:var(--clearcoat) }

/* ── the offer strip ──────────────────────────────────────────────────── */
/* ⭐ What the customer actually gets, in the site's own sentence. ⛔ Never a
   price, a rating or a count — this demo has published none of those. */
.offerbar{
  border-bottom:1px solid var(--line);
  background-image:linear-gradient(180deg,#111216,#0a0a0c);
}
.offerbar__in{
  display:flex; align-items:center; gap:1rem; flex-wrap:wrap;
  padding-top:.65rem; padding-bottom:.65rem;
}
.offerbar__tag{
  font-family:var(--mono); font-size:.66rem; text-transform:uppercase;
  letter-spacing:.16em; color:var(--clearcoat);
  border:1px solid rgba(127,212,232,.38);
  border-radius:999px; padding:.2rem .6rem; flex:0 0 auto;
}
.offerbar__msg{
  margin:0; font-size:.84rem; line-height:1.5; color:var(--mute);
  flex:1 1 340px; min-width:0;
}
.offerbar__msg b{ color:var(--ink); font-weight:600 }
.offerbar__go{
  flex:0 0 auto; font-family:var(--mono); font-size:.68rem; text-transform:uppercase;
  letter-spacing:.12em; color:var(--ink); text-decoration:none; white-space:nowrap;
  border-bottom:1px solid rgba(127,212,232,.55); padding-bottom:2px;
  transition:color var(--t) var(--ease), border-bottom-color var(--t) var(--ease);
}
.offerbar__go:hover{ color:var(--clearcoat); border-bottom-color:var(--clearcoat) }
@media (max-width:640px){
  .offerbar__go{ display:none }        /* the hero button is just below it */
  .offerbar__msg{ font-size:.8rem }
}

/* ── the hero now has a call to action, and it is the accent ──────────── */
/* 🔴 The first button on this page used to be 540 lines down. A hero with no
   action is the difference this pass was called to close. */
.btnrow{ display:flex; flex-wrap:wrap; gap:.75rem; align-items:center; margin:2rem 0 0 }
.btn{
  background:var(--clearcoat); border-color:var(--clearcoat); color:var(--clearcoat-ink);
  font-weight:700;
}
.btn:hover{ background:var(--clearcoat-hi); border-color:var(--clearcoat-hi); color:var(--clearcoat-ink) }
.btn::after{
  background:linear-gradient(100deg, rgba(255,255,255,0) 36%, rgba(255,255,255,.34) 50%, rgba(255,255,255,0) 64%);
}

/* ── depth on the drawn car ───────────────────────────────────────────── */
.hero__art{
  filter:drop-shadow(0 3rem 4.5rem rgba(0,0,0,.85)) drop-shadow(0 .4rem 1rem rgba(0,0,0,.6))
         contrast(1.06) saturate(1.05);
}

@media (prefers-reduced-motion:reduce){
  .brand:hover .brandmark{ transform:none }
}

/* 🔴 AND THE GHOST IS RESTATED AFTER IT. `.btn` is declared twice above — at
   ~275 and again at ~406 — and this file is unlayered, so a `.btn` rule down
   here, at the same specificity and later in the source, takes the background
   from anything that merely modifies it. `.btn--ghost` therefore has to sit
   BELOW the `.btn` block above, or both buttons render solid cyan and two
   primaries is no primary. ⛔ Any future `.btn` rule appended below this point
   must restate the ghost again. */
.btn--ghost{
  background:transparent; border-color:var(--line-2); color:var(--ink); font-weight:400;
}
.btn--ghost:hover{
  background:var(--clearcoat-wash); border-color:var(--clearcoat); color:#fff;
}
.btn--ghost::after{
  background:linear-gradient(100deg, rgba(127,212,232,0) 36%, rgba(127,212,232,.16) 50%, rgba(127,212,232,0) 64%);
}

/* ── 🚿 THE DAY, AS THE CUSTOMER HAS IT — 11 Sep 2026 ─────────────────────
   ⭐ The old h1 led with what the STUDIO did and did not do, which is our
   argument, not the customer's. What a person actually buys from a detailer is
   a car they stop apologising for — and the only reason to buy it here is that
   the gloss was not bought with clear coat. So the headline names the trade and
   the town, the accent carries the customer's half, and this section walks the
   day the car is in the bay.
   ⛔ Every beat is something one bay could really do in a day and a night.
   Nothing here says a slot is held. 11:05 is a REFUSAL — the declined line at
   $0.00 that is already on the example report further down this page.
   ⭐ COLOUR DISCIPLINE. --clearcoat is the one decisive accent and it appears
   in five places. It is not spent on eleven timestamps: those are mono in
   --mute, and clearcoat marks exactly ONE beat — the moment the promise in the
   headline actually happens. Annotation for the refusal comes from --accent,
   the champagne that is used almost nowhere. */
.sec--day .day{list-style:none;margin:2rem 0 0;padding:0;display:grid;gap:0}
.day__i{
  display:grid;grid-template-columns:5.5rem 1fr;gap:0 1.5rem;
  padding:1.35rem 0;border-top:1px solid var(--line);align-items:start;
}
.day__i:first-child{border-top:0}
.day__t{
  font-family:var(--mono);font-size:.75rem;letter-spacing:.08em;
  color:var(--mute);padding-top:.42rem;font-variant-numeric:tabular-nums;
}
.day__t em{
  display:block;font-style:normal;font-size:.625rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mute-2);margin-top:.2rem;
}
.day__i h3{
  font-family:var(--display);font-weight:400;font-size:clamp(1.1rem,2.1vw,1.45rem);
  line-height:1.2;margin:0 0 .45rem;letter-spacing:-.01em;
}
.day__i p{margin:0;font-size:.9375rem;line-height:1.7;color:#b9b2a8;max-width:60ch}
.day__i p b{color:var(--accent-warm);font-weight:400}
/* ⛔ the refusal is annotated in champagne, never in the primary accent */
.day__i--no .day__t{color:var(--accent)}
/* ⭐ ONE marked beat, and it is the handover — the moment "the car you stop
   apologising for" stops being a headline and becomes a car in your hand. */
.day__i--live .day__t{color:var(--clearcoat)}
.day__i--live .day__t::after{
  content:"";display:block;width:5px;height:5px;border-radius:50%;
  background:var(--clearcoat);margin-top:.5rem;
}
.day__foot{
  margin:1.75rem 0 0;padding-top:1.35rem;border-top:1px solid var(--line);
  font-size:.9375rem;line-height:1.7;color:#b9b2a8;max-width:62ch;
}
.day__foot b{color:var(--ink);font-weight:400}
@media (max-width:34rem){
  .day__i{grid-template-columns:1fr;gap:.4rem}
  .day__t{padding-top:0}
  .day__t em{display:inline;margin-left:.6rem}
  .day__i--live .day__t::after{display:inline-block;margin:0 0 .1rem .55rem;vertical-align:middle}
}

/* 🔴 THE GRID HAD THREE CHILDREN AND TWO COLUMNS. `.day__i` holds a timestamp,
   an <h3> and a <p>. Auto-placement puts the timestamp at 1/1, the heading at
   1/2 and then wraps the PARAGRAPH back to 2/1 — the timestamp column — so every
   beat's prose rendered in an 84px ribbon one or two words wide and ~330px tall.
   It looked like a layout, so nothing about it read as an error.
   ⛔ Both text children must be pinned to column 2 explicitly. Never rely on
   auto-placement to keep a two-column row on one row. */
.day__i h3,.day__i p{grid-column:2}
@media (max-width:34rem){ .day__i h3,.day__i p{grid-column:1} }


/* ── 📷 PHOTOGRAPHS ───────────────────────────────────────────────────────
   🔴 11 Sep 2026. Owner: "need photos!!" and "no stick diagrams". This demo
   shipped with none, and a page of line drawings reads as a prototype rather
   than as a business's site.

   ⭐ PORTABLE ON PURPOSE. Thirteen demos, thirteen different token names —
   --soil/--panel/--hair here, --paper/--rule/--gr there, light and dark both.
   A component written against one demo's variables is a component that has to
   be rewritten twelve times and will be wrong in four of them. So this uses
   `currentColor` and plain rgba, and inherits the page's own ink.

   ⛔ Every CC BY / CC BY-SA frame carries its credit IN the frame. Attribution
   is a licence term, not a courtesy, and "we'll add the credits later" is
   exactly how a licence gets breached. */
.photo{position:relative;margin:0;line-height:0;border-radius:4px;overflow:hidden;
  border:1px solid rgba(128,128,128,.28)}
.photo img{width:100%;display:block;object-fit:cover;filter:saturate(1.03) contrast(1.02)}
.photo--hero img{height:clamp(260px,34vw,430px)}
.photo--band img{height:clamp(190px,26vw,320px)}
.photo--tall img{height:clamp(240px,30vw,380px)}
/* ⚠️ the badge carries its OWN scrim rather than the frame carrying a gradient.
   A gradient tuned for a dark ground turns a light photo muddy along the bottom,
   and half these demos are light. */
.photo__cr{position:absolute;right:8px;bottom:8px;z-index:2;
  font-size:.59375rem;letter-spacing:.04em;line-height:1.45;font-weight:500;
  color:rgba(255,255,255,.88);background:rgba(0,0,0,.52);padding:3px 7px;border-radius:2px;
  text-shadow:0 1px 2px rgba(0,0,0,.5)}
.photo__cr a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.photo__cap{line-height:1.55;font-size:.78125rem;opacity:.72;padding-top:9px}

/* ── 🚪 THE WAY OUT STAYS ON SCREEN ───────────────────────────────────────
   🔴 11 Sep 2026, owner: "need to be able and x out of all the demo sites if
   you view on mobile dont let people get stuck somewher with out easy exit."

   This banner is the only route from a demo back to us, and it sat at the top
   of the document as a static block. On a phone, two swipes down a service page
   and it is gone — a visitor who arrived on a shared link has no way back and
   no reason to think one exists. ⚠️ The link was always there and was always
   unreachable, which is the same shape as the embed's close button being parked
   off-screen above the iframe.

   ⭐ Sticky on phones only. On a desktop the banner is in view at the top of a
   page people can see all of, and pinning it would just spend vertical room. */
@media (max-width: 640px) {
  .demostrip {
    position: sticky;
    top: 0;
    z-index: 90;
  }
  /* ⚠️ AND THE LINK HAS TO BE HITTABLE, NOT MERELY PRESENT. It is inline text
     inside a sentence, so on a 375px screen it wrapped into two fragments 15px
     tall — measured, both genuinely tappable, and both far under the 44px a
     thumb needs. ⭐ Make it a control: one line, real padding, no wrap. */
  .demostrip a {
    display: inline-block;
    margin-top: 4px;
    padding: 11px 12px;
    white-space: nowrap;
    font-weight: 700;
  }
}


/* 🔴 INSIDE OUR OWN FRAME THE BANNER IS DUPLICATE — 11 Sep 2026. Owner, looking
   at the embed on the home page: "take all of this off this is awfull they know
   that". He is right about that surface: our own chrome prints a disclosure
   directly under the frame, in our voice, so the demo's banner made two stacked
   notices — which reads as nervous rather than as honest.
   ⛔ A STANDALONE PAGE KEEPS IT. There the banner is the ONLY notice, and these
   pages carry a live telephone line: an invented business with a working number
   and nothing saying so is a trap, not a demo.
   ⚠️ Fails in the honest direction — with JavaScript off, nothing is hidden.
   ⛔ If the note under the frame is ever removed, delete this rule first. */
html[data-embedded] .demostrip { display: none !important; }


/* ── 🧭 THE UTILITY BAR — 15 Sep 2026 ─────────────────────────────────
   Written by tools/demo-utilbar.mjs. See that file for why the disclosure
   banner became a chip and why hours are absent on the demos that publish none.
   ⛔ Self-contained colour on purpose: every demo means something different by
   --ink, and borrowing it painted this a different thing on each site. */
.utilbar{background:#0f1b2a;color:rgba(255,255,255,.92);
  border-bottom:1px solid rgba(255,255,255,.14);font-size:.78rem;line-height:1.4;
  font-family:system-ui,-apple-system,"Segoe UI",sans-serif}
.utilbar__in{display:flex;align-items:center;justify-content:space-between;
  gap:.9rem;min-height:38px;padding:.3rem 20px;flex-wrap:wrap;
  max-width:1180px;margin:0 auto}
.utilbar__hours{margin:0;display:flex;align-items:center;gap:.45rem;min-width:0}
.utilbar__hours b{font-weight:600;color:#fff}
.utilbar__sep{opacity:.45}
.utilbar__hours>span:last-child{opacity:.72}
.utilbar__right{display:flex;align-items:center;gap:.9rem;flex-wrap:wrap;min-width:0}
.utilbar__lnk{color:rgba(255,255,255,.88);text-decoration:none;
  border-bottom:1px solid rgba(255,255,255,.26);padding-bottom:1px}
.utilbar__lnk:hover{color:#fff;border-bottom-color:#fff}
/* ⭐ colour is never the only carrier — the words say Open or Closed outright */
.utilbar__dot{width:8px;height:8px;border-radius:50%;flex:0 0 auto;background:#7fe0a8}
.utilbar__hours[data-state="open"] .utilbar__dot{background:#7fe0a8;animation:utilpulse 3s ease-out infinite}
.utilbar__hours[data-state="soon"] .utilbar__dot{background:#ffc861}
.utilbar__hours[data-state="shut"] .utilbar__dot{background:#9aa6b1}
@keyframes utilpulse{0%{box-shadow:0 0 0 0 rgba(127,224,168,.5)}
  70%{box-shadow:0 0 0 6px rgba(127,224,168,0)}100%{box-shadow:0 0 0 0 rgba(127,224,168,0)}}
@media (prefers-reduced-motion:reduce){.utilbar__dot{animation:none !important}}
.utilbar .demostrip{display:inline-flex;align-items:center;gap:.4rem;
  padding:.16rem .55rem;border-radius:999px;background:rgba(255,255,255,.10);
  border:1px solid rgba(255,255,255,.22);font-size:.72rem;color:#fff;
  text-decoration:none;cursor:pointer}
.utilbar .demostrip:hover{background:rgba(255,255,255,.18);border-color:rgba(255,255,255,.38)}
.utilbar .demostrip b{text-transform:uppercase;letter-spacing:.08em;font-size:.68rem;font-weight:700}
.utilbar .demostrip__dot{width:7px;height:7px;border-radius:50%;background:#ff6a55;display:block}
@media (max-width:860px){
  /* ⛔ the TAIL hides, never the notice — and the chip becomes the link to it */
  .utilbar__demotail{display:none}
  .utilbar__in{gap:.55rem}
  .utilbar__right{gap:.7rem}
  .utilbar .demostrip{min-height:30px}
}
@media (max-width:560px){
  .utilbar{font-size:.72rem}
  .utilbar__hours>span:last-child,.utilbar__sep{display:none}
  .utilbar .demostrip{min-height:34px;padding-inline:.7rem}
}
/* ⛔ Inside our own iframe the surrounding chrome carries the disclosure, so the
   chip is hidden there and ONLY there. A standalone page always keeps it. */
html[data-embedded] .utilbar .demostrip{display:none !important}

/* 🔴 NO STATUS LIGHT WITHOUT A STATUS — 15 Sep 2026. Six of these demos publish
   no hours at all, and one publishes "by appointment". The dot is a status
   light: green, beside a company name with nothing behind it, it silently says
   OPEN NOW about a business whose hours nobody ever wrote. It only appears once
   the script has decided a real state from real published hours.
   ⚠️ This shipped for one sync because the fix was written into a script that
   died on an assertion BEFORE the file was saved — the edit was reported and
   never landed. Verify the artefact, not the log line. */
.utilbar__hours:not([data-state]) .utilbar__dot{display:none}


/* ── 🖼️ THE PHOTOGRAPH IS THE HERO — 15 Sep 2026 ─────────────────────────
   Written by tools/demo-photo-hero.mjs; the reasoning lives there. */
.lanaihero{position:relative;isolation:isolate;display:flex;flex-direction:column;justify-content:center;
  min-height:clamp(330px,62vh,600px);overflow:hidden;background:#07182a}
.lanaihero>img{position:absolute;inset:0;z-index:0;width:100%;height:100%;
  object-fit:cover;object-position:center 58%}
/* 🔴 TWO GRADIENTS, BOTH LOAD-BEARING. The horizontal one carries the headline;
   the vertical one holds the eyebrow and the buttons, which sit where the
   horizontal scrim has already thinned out. */
.lanaihero__scrim{position:absolute;inset:0;z-index:1;
  background:
    linear-gradient(90deg, rgba(5,18,32,.93) 0%, rgba(5,18,32,.86) 38%,
                           rgba(5,18,32,.46) 70%, rgba(5,18,32,.24) 100%),
    linear-gradient(0deg,  rgba(5,18,32,.42) 0%, rgba(5,18,32,.30) 50%,
                           rgba(5,18,32,.14) 100%)}
/* ⛔ padding-block, never the shorthand — a `padding: X 0 Y` here wipes the
   horizontal gutter the wrap class contributes and every line goes flush to the
   edge of the screen. That shipped once. */
.lanaihero__in{position:relative;z-index:2;
  padding-block:clamp(2rem,5vw,3.4rem) clamp(1.9rem,4.5vw,3rem)}
.lanaihero h1{color:#fff;max-width:20ch;text-wrap:balance}
.lanaihero .h1__where{color:#fff}
.lanaihero .hl{color:rgba(255,255,255,.74)}
.lanaihero .eyebrow,.lanaihero .lbl,.lanaihero .kicker{color:rgba(255,255,255,.88)}
.lanaihero .btnrow,.lanaihero .hero__act{margin-top:1.4rem;display:flex;flex-wrap:wrap;gap:.7rem}
/* ⛔ A ghost/outline button is a hairline on paper; over a photograph it
   disappears. WCAG 2.2 asks 3:1 for the control's own boundary, not just its
   label. */
.lanaihero .btn--ghost,.lanaihero .btn--line,.lanaihero .btn--out{
  border-color:rgba(255,255,255,.62);color:#fff;background:rgba(7,22,38,.42);
  -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
.lanaihero .btn--ghost:hover,.lanaihero .btn--line:hover,.lanaihero .btn--out:hover{
  background:rgba(7,22,38,.66);border-color:#fff}
.lanaihero .photo__cr{position:absolute;right:10px;bottom:9px;z-index:3;
  font-size:.625rem;color:rgba(255,255,255,.8);background:rgba(0,0,0,.5);
  padding:3px 7px;border-radius:3px}
.lanaihero .photo__cr a{color:inherit}
@media (max-width:640px){
  /* ⚠️ At phone width the headline spans the full column, so a left-weighted
     gradient leaves its right-hand words over bright sky. Mostly vertical here. */
  .lanaihero{min-height:clamp(300px,52vh,420px)}
  .lanaihero__scrim{background:
    linear-gradient(0deg, rgba(5,18,32,.80) 0%, rgba(5,18,32,.72) 50%,
                          rgba(5,18,32,.55) 100%),
    linear-gradient(90deg, rgba(5,18,32,.55) 0%, rgba(5,18,32,.30) 100%)}
  .lanaihero h1{max-width:none}
}




/* 🔴 THE HERO BUTTONS — 15 Sep 2026. Owner: "make sure the buttons are spread
   out and even across heros", "not sqished into the tiltles".
   Measured at 1280 before touching anything: rv-powersports had its buttons
   touching the headline at a gap of ZERO, because its row is `.hero__cta` and
   the rule only named `.btnrow` and `.hero__act`. The rest sat at 22px with an
   11px gap between them and heights running 40 to 53.
   ⭐ One rule, all three row names, and a floor under the height so a row of
   buttons reads as a row rather than as two different controls. */
.lanaihero .btnrow,
.lanaihero .hero__act,
.lanaihero .hero__cta{
  margin-top:clamp(1.6rem,2.6vw,2.2rem);
  display:flex; flex-wrap:wrap; align-items:center;
  gap:.85rem;
}
.lanaihero .btn{
  min-height:48px;
  display:inline-flex; align-items:center; justify-content:center;
  padding-inline:1.25rem;
}
@media (max-width:560px){
  /* ⚠️ Full width and stacked on a phone — two half-width buttons side by side
     put both under the 48px the thumb needs in the direction that matters. */
  .lanaihero .btnrow,.lanaihero .hero__act,.lanaihero .hero__cta{gap:.65rem}
  .lanaihero .btn{width:100%}
}


/* ── 👥 THE SOCIAL MARKS — 15 Sep 2026. Owner: "put fake no link social on the
   headers", after twice being told there is nowhere honest to point them.
   ⛔ THEY ARE NOT LINKS, AND THAT IS THE POINT. These companies are invented,
   so a social icon could only lead to an invented profile, to somebody else's
   real account, or to nothing — and a control that goes nowhere is worse than
   no control. They are `<span>` marks, `aria-hidden`, not focusable and not
   clickable: an illustration of where a real client's profiles sit in the bar,
   on a page that already says it is a demonstration.
   ⛔ Do not turn these into <a> on a real build without real profiles behind
   them. Bots On Staff's own Facebook and Instagram have never published once. */
.utilbar__social{display:inline-flex;align-items:center;gap:.55rem;opacity:.62}
.utilbar__social svg{width:15px;height:15px;display:block}
@media (max-width:560px){ .utilbar__social{display:none} }


/* 🔴 THE GHOST BUTTON, RESTATED BELOW `.btn` — 15 Sep 2026.
   The polish gate refused four demos for this and it was right: adding a
   `.lanaihero .btn` block after the ghost rules puts the outline variant at the
   mercy of source order in unlayered CSS. It happens that the block above sets
   no background, so nothing rendered wrong — but "it happens to be fine" is not
   a property anyone can rely on while editing this file later.
   ⛔ Any new `.btn` rule goes ABOVE this, or this moves below it. */
.lanaihero .btn--ghost,
.lanaihero .btn--line,
.lanaihero .btn--out{
  border-color:rgba(255,255,255,.62);
  color:#fff;
  background:rgba(7,22,38,.42);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
}
.lanaihero .btn--ghost:hover,
.lanaihero .btn--line:hover,
.lanaihero .btn--out:hover{background:rgba(7,22,38,.66);border-color:#fff}

.lanaihero .btn--ghost{
  border-color:rgba(255,255,255,.62);
  color:#fff;
  background:rgba(7,22,38,.42);
}


/* ── 📣 THE OFFER BAND, ON THE PHOTOGRAPH — 15 Sep 2026 ──────────────────────
   Owner: "i dont think it needs the white section evry vist", then "figure it
   out in a great spot dont just throw it somewhere be creative".
   🔴 IT CANNOT SIMPLY GO. The polish gate requires an offer strip on every page
   and it is right to — it is the one line on a demonstration site that says what
   the shop actually promises. But as a white slab wedged between the header and
   the hero it interrupted the only picture on the page before anyone had seen it.
   ⭐ So it is pinned to the FOOT of the hero, over the photograph, on the same
   dark glass as the scrim. The promise now reads as part of the image instead of
   as an announcement above it, and the page opens header -> photograph -> story
   with nothing cutting across.
   ⛔ Its own backdrop is near-opaque on purpose: type over a photograph is the
   one thing on this estate that has been measured wrong twice, and a band that
   carries its own ground cannot drift when the picture changes. */
.lanaihero{padding-bottom:0}
.lanaihero .offerbar{
  position:absolute; left:0; right:0; bottom:0; z-index:3;
  background:rgba(6,19,34,.86);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  border-top:1px solid rgba(255,255,255,.16);
  border-bottom:0;
}
.lanaihero .offerbar__in{
  display:flex; align-items:center; gap:1rem; flex-wrap:wrap;
  padding-block:.7rem;
}
.lanaihero .offerbar__tag{
  color:#fff; border-color:rgba(255,255,255,.45); background:rgba(255,255,255,.10);
}
.lanaihero .offerbar__msg{color:rgba(255,255,255,.92); margin:0}
.lanaihero .offerbar__msg b{color:#fff}
.lanaihero .offerbar__go{color:#fff; border-color:rgba(255,255,255,.5)}
/* ⚠️ the hero's own content must clear the band, or the buttons sit under it */
.lanaihero__in{padding-bottom:clamp(5.5rem,9vw,7rem)}
@media (max-width:860px){
  /* ⛔ On a phone the band would eat the picture. It goes back into the flow
     directly beneath the hero — still out from between the header and the photo,
     which is the thing that was wrong. */
  .lanaihero .offerbar{position:static;backdrop-filter:none;-webkit-backdrop-filter:none}
  .lanaihero__in{padding-bottom:clamp(1.9rem,4.5vw,3rem)}
}


/* ══ 🧭 THE HEADER, 2026 — 15 Sep 2026 ══════════════════════════════════════
   Owner: "the header need to be way better on each site look like proper 2026
   header trends", "make sure everyting looks as goos as outr customer sites".
   🔴 MEASURED FIRST, ALL TWELVE AT 1280: heights ran from 62px to 223px, only
   one was sticky, and eleven carried a telephone number that the new utility bar
   was already showing a few pixels above it.
   ⭐ This layer is keyed on the `header` ELEMENT, not on a class, because these
   demos call it .site, .top, .mast, .nav and .masthead — five names for one
   thing. Anything that needs a class name is done per demo.
   ⛔ It is deliberately visual-only: sticky, glass, a hairline that appears on
   scroll, and honest focus rings. It does not re-order anybody's markup. */
header{
  position:sticky; top:0; z-index:60;
  -webkit-backdrop-filter:saturate(1.3) blur(10px);
  backdrop-filter:saturate(1.3) blur(10px);
  transition:box-shadow .22s ease, border-color .22s ease;
}
/* ⭐ The rule under the header only appears once you have scrolled — a border
   that is always there is chrome, a border that arrives is depth. */
header::after{
  content:""; position:absolute; left:0; right:0; bottom:-1px; height:1px;
  background:currentColor; opacity:0; transition:opacity .22s ease;
  pointer-events:none;
}
html[data-scrolled] header::after{opacity:.16}
html[data-scrolled] header{box-shadow:0 10px 30px -22px rgba(0,0,0,.55)}

/* ⛔ 44px is not decoration. WCAG 2.2 §2.5.8, and on a phone this is the only
   navigation there is. */
@media (max-width:900px){
  header nav a{min-height:44px;display:flex;align-items:center}
}
/* a focus ring that is visible on both a light and a dark header */
header a:focus-visible, header button:focus-visible, header label:focus-visible{
  outline:2px solid currentColor; outline-offset:3px; border-radius:6px;
}


/* 🔴 STICKY WAS LOSING ON SPECIFICITY — 15 Sep 2026. `header{position:sticky}`
   is (0,0,1) and these demos set `.top{position:relative}` at (0,1,0), so five
   of twelve silently stayed put while the other seven pinned. Measured, not
   assumed: auto-detailing, drain-cleaning, mobile-repair, plumbing-hvac and
   rv-powersports all read `relative` after the layer went in.
   ⭐ `header[class]` is (0,1,1) and beats a single class without reaching for
   !important, which would then have to be fought later. */
header[class]{position:sticky;top:0;z-index:60}

/* 🔴 THE OFF-CANVAS MENU WAS WIDENING THE PAGE. Parked at translateX(102%) the
   panel still counted toward scrollWidth — 700px against a 371px viewport — so
   the whole site scrolled sideways on a phone with nothing visible to scroll to.
   ⛔ `overflow-x:hidden` would fix it and break `position:sticky` in the same
   stroke; `clip` does not create a scroll container, so the header still pins. */
html{overflow-x:clip}


/* 🔴 THE NAV WAS WRAPPING ONTO ITS OWN ROW — 15 Sep 2026, measured at 1280.
   These headers are flex rows that ran out of width, so the navigation dropped
   beneath the brand and the header doubled in height: 134, 138, 104, 223.
   A sticky header that tall eats a quarter of a laptop screen, and it is the
   clearest difference between these and the client sites.
   ⭐ One row, and the NAV is the part allowed to give — `min-width:0` lets it
   shrink, and if it still will not fit it scrolls sideways within itself rather
   than pushing the whole header down. ⛔ `scrollbar-width:none` hides the bar,
   not the ability to scroll; the items remain reachable by wheel, trackpad,
   touch and keyboard. */
@media (min-width:901px){
  header .top__in,
  header .masthead__row,
  header .brandline{flex-wrap:nowrap}
  header nav{min-width:0}
}
@media (min-width:901px){
  header nav ul{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}
  header nav ul::-webkit-scrollbar{display:none}
  header nav a{white-space:nowrap}
}

/* 🔴 223px, THE TALLEST OF THE TWELVE. Its `.wrap` is a BLOCK holding the brand
   row and the navigation as siblings, so they could never share a line, and it
   carried 44px of padding above and 32 below on top of that. */
@media (min-width:901px){
  header .wrap{display:flex;align-items:center;gap:clamp(1rem,2.5vw,2rem);flex-wrap:nowrap}
  header .brandline{flex:0 1 auto;min-width:0}
  header nav.site{flex:1 1 auto;min-width:0;display:flex;justify-content:flex-end}
}
header{padding-block:.5rem}


/* 🔴 THE PADDING, NOT THE LAYOUT — 15 Sep 2026. Having got these headers onto
   one row, they were still 93-193px, and the cause was the same specificity
   mistake as the sticky rule: `header{padding-block:.5rem}` is (0,0,1) and
   `.site{padding:44px 0 32px}` is (0,1,0), so the trim never applied. Measured
   on auto-detailing: brand row 112px inside 44px above and 32px below.
   ⭐ `header[class]` wins without reaching for !important.
   ⚠️ This trims the ROOM around the brand, not the brand. What is left is each
   demo's own lockup at its own size — a 112px logo-and-tagline block is a
   design decision, and shrinking it would be changing their identity rather
   than tightening their chrome. */
header[class]{padding-block:clamp(.45rem,1vw,.8rem)}


/* 🔴 ONE HERO WAS 83vh BECAUSE ITS HEADLINE WAS 104px — 15 Sep 2026.
   Owner: "make sure desktop hero are proper sixe". Measured at 1280: nine
   heroes sat at 62-66vh and auto-detailing at 83vh, and the cause was not the
   hero box at all — its <h1> renders at 104px over three lines, 306px of type.
   That size was tuned for a hero made ONLY of words; over a photograph it is
   shouting. ⭐ Capped to the size the rest already use, so the set reads as one
   family. ⛔ Still large text for contrast purposes (>=24px), so the 3:1
   threshold the probe applies is unchanged. */
.lanaihero h1{font-size:clamp(2rem,4.4vw,3.5rem);line-height:1.06}


/* ══════════════════════════════════════════════════════════════════════════
   ⚠️ HAND-EDITED — THIS SHEET NOW DIVERGES FROM ITS GENERATOR. 23 Sep 2026.
   The header at the top of this file says this demo is written out of
   ~/Desktop/demo-detailing/dist by tools/sync-demo.mjs and must not be edited by
   hand. Everything below this line was written BY HAND anyway, on the owner's
   instruction, and the generator knows nothing about it.
   ⛔ DO NOT RUN tools/sync-demo.mjs OR build.py FOR THIS DEMO. A sync would
   revert every rule below without printing a word — the exact failure the
   estate has already paid for once ("a hand-edit to a generated file reverts
   silently — build green, fix gone").
   ⭐ WHY THIS IS THE RIGHT WAY ROUND ANYWAY: the generator source lives outside
   this repo, is untracked and unbacked, and at least one of these demos
   provably no longer reproduces its published copy. public/demo IS in git. So
   public/demo is the authority now. If the generator is ever restored, port
   these blocks into it FIRST and diff its output before syncing anything.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1. ONE HERO, NOT TWO ─────────────────────────────────────────────────
   🔴 This page opened with <section class="lanaihero"> and then a SECOND
   <section class="hero"> immediately underneath. Ten of the thirteen demos
   did. Two hero bands is a stack, and a stack has no first thing to look at —
   the same defect the Cut Above home page was rebuilt six times for.
   ⭐ The second band is now `.showcase`: a content band that keeps its ground,
   its drawing and its photograph, and has no headline, no eyebrow and no lede
   restating what the h1 already said. The rules it needs were added to the
   `.hero` selectors above rather than duplicated, so the two cannot drift. */

/* ── 2. THE HEADLINE IS AT LEAST 3.0x BODY AT EVERY WIDTH ─────────────────
   🔴 Measured before this pass: the hero headline fell to **1.88x** body on a
   phone. `.lanaihero h1` capped it at 2rem — correctly, because 104px over
   three lines had made one hero 83vh — but the floor went with the ceiling.
   A headline under 2x body is not a headline, it is a bold paragraph.
   ⭐ THE FIX IS ARITHMETIC, NOT TASTE, and it is this pair:
        body  1rem (16px) up to 740px, 1.0625rem above it
        h1    clamp(3rem, 7vw, …)
   The worst point is 741px, where body jumps to 17px while 7vw is only
   51.87px — 3.05x, the tightest the whole range gets. At 320px it is 48/16 =
   3.00x exactly. ⛔ Do not lower either number without recomputing 741px.
   ⚠️ The 3.5rem ceiling on the hero headline is deliberately unchanged: that
   number was measured, and raising it is how a hero became 83vh tall. */
@media (max-width:740px){ body{font-size:1rem} }

/* ── 3. THE HERO IS THE DOCUMENT ──────────────────────────────────────────
   ⭐ The most persuasive object this business has is a job it turned DOWN: one
   real line on a real document, at $0.00, with a reason a customer can go and
   check. It was buried mid-page behind two hundred words of lede. It is now
   the offer strip itself, at the fold, and **$0.00 is a literal in the
   markup** — not a badge, not a rounded claim, not a rating. There are no
   ratings, stars or review counts anywhere on this site and there never will
   be; this is the honest version of the same job.
   ⛔ THE WRAPPER KEEPS `offerbar` IN ITS CLASS LIST ON PURPOSE.
   tools/check-demo-polish.mjs requires an offer strip on every page of every
   demo. Renaming the class here would strip it from the gate's view.
   ⚠️ COLOUR, AND WHY NOTHING COLOURED CARRIES TEXT. This band is
   rgba(6,19,34,.86) over a photograph, so with a white photo behind it it
   composites to roughly #293340 — dark, but not as dark as it looks in a
   screenshot of a dark picture. Every foreground below is white or near-white
   against that. The one coloured thing is the 3px flag rule, which carries no
   glyphs and so answers to the 3:1 non-text floor, not 4.5:1. */
.lanaihero .herodoc{ box-shadow:inset 0 3px 0 var(--doc-flag); }
.herodoc__in{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;
  column-gap:clamp(.8rem,2vw,1.5rem);
  row-gap:.5rem;
  padding-block:clamp(.8rem,1.7vw,1.1rem);
}
.herodoc__tag{
  grid-column:1; grid-row:1;
  font-family:var(--mono); font-size:.625rem; font-weight:700;
  letter-spacing:.2em; text-transform:uppercase; white-space:nowrap;
  color:#fff; background:rgba(255,255,255,.12);
  border:1px solid rgba(255,255,255,.42); border-radius:2px;
  padding:.3rem .55rem; align-self:center;
}
.herodoc__it{
  grid-column:2; grid-row:1;
  font-weight:600; line-height:1.25; color:#fff;
  font-size:clamp(.9375rem,1.5vw,1.0625rem);
  text-shadow:0 1px 2px rgba(0,0,0,.70);
}
/* ⛔ Not a muted grey. Over a picture the picture is already doing the
   de-emphasising, and a dimmed foreground on a busy ground is just an
   unreadable foreground. Near-full ink, plus a shadow that travels with the
   glyphs rather than a panel that darkens the photograph. */
.herodoc__why{
  display:block; margin-top:.22rem; max-width:52ch;
  font-family:var(--mono); font-style:normal; font-weight:400;
  font-size:.75rem; line-height:1.5; letter-spacing:.01em;
  color:rgba(255,255,255,.93);
  text-shadow:0 1px 2px rgba(0,0,0,.70);
}
/* ⭐ tabular figures, so the amount reads as money in a column rather than as
   a word in a sentence. That is what makes it look like a document. */
.herodoc__amt{
  grid-column:3; grid-row:1;
  font-family:var(--mono); font-weight:700; color:#fff; white-space:nowrap;
  font-size:clamp(1.25rem,2.4vw,1.6rem); letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;
  text-shadow:0 1px 2px rgba(0,0,0,.70);
}
/* ⛔ At 640px three columns stop fitting and the reason column collapses to a
   word per line. The flag and the amount stay together on the first row —
   they are the two things that must be read as one statement — and the line
   itself wraps underneath at full width. Nothing is lost at 320px. */
@media (max-width:640px){
  .herodoc__in{ grid-template-columns:auto minmax(0,1fr); }
  .herodoc__amt{ grid-column:2; grid-row:1; justify-self:end; }
  .herodoc__it{ grid-column:1 / -1; grid-row:2; }
}

/* ── 4. THE SCALE, RESTATED ABOVE THE CAP ─────────────────────────────────
   Three rules set this site's h1 and the last one won at the small end. All
   three now sit above 3.0x body. ⚠️ `.hero h1` at >=900px governs the INTERIOR
   pages, which still open with a `.hero` title block — it was 2.75x there. */
h1{ font-size:clamp(3rem,7vw,6.5rem); }
.lanaihero h1{ font-size:clamp(3rem,7vw,3.5rem); line-height:1.04; }
@media (min-width:900px){ .hero h1{ font-size:clamp(3.25rem,5.2vw,4rem); } }

/* ── 5. THE DOOR THAT WAS NOT THERE ───────────────────────────────────────
   🔴 This hero had NO call to action at all — the only demo in the set with a
   photograph, a headline and nowhere to go. Both doors are in the hero now. */

/* the flag rule's colour: --accent-warm, the champagne this site already reserves for its one accent */
:root{ --doc-flag:#e6d5ae; }

/* ── 6. THE BAND THAT USED TO SIT HERE IS GONE, SO ITS AIR MUST BE RESTORED
   The second hero became `.showcase`, then lost its drawing and its lede and
   was left an empty ~180px of black between the $0.00 document and the first
   real section — so it was removed outright. But `section+section{padding-top:0}`
   then applied to the section that followed it, and the story ran straight into
   the underside of the document bar.
   ⛔ Removing an element is a spacing change. The rule that gave the removed
   element's NEIGHBOUR its air has to move with it. */
.lanaihero + section{ padding-top:var(--air) }

/* ── 7. GLASS — A HARD-EDGED PLATE ────────────────────────────────────────
   Owner, 23 Sep 2026: "use glass buttons all the newest elements".

   ⛔ THE RULE THAT MATTERS, AND IT IS NOT A STYLE RULE. The hero is a
   full-bleed photograph, so the moment a button stops being an opaque fill,
   the contrast of its LABEL is decided by the picture, not by a colour anyone
   chose. `backdrop-filter` is also unsupported, switched off, or dropped under
   forced-colors for a real share of readers.
   ⭐ SO THE BACKGROUND ALPHA IS SET HIGH ENOUGH TO CLEAR 4.5:1 WITH NO BLUR AT
   ALL, and the blur is only an enhancement on top of a background that already
   passes. Proved by tools/check-hero-button-contrast.mjs, which measures glyph
   pixels at three widths in BOTH states. ⛔ Do not lower an alpha here without
   re-running it.

   ⭐ THE MATERIAL IS THIS SITE'S OWN. Square corners and a hairline — the same
   hard edge as the chamfered plate in the mark and the square buttons the rest
   of the site already uses. ⛔ It is deliberately NOT the translucent pill the
   other three wear; glass is a material, not one shape. */
.lanaihero .btn{
  border-radius:0;
  -webkit-backdrop-filter:blur(14px) saturate(1.18);
  backdrop-filter:blur(14px) saturate(1.18);
}
/* PRIMARY — tinted glass carrying the brand colour at high opacity, dark ink.
   ⚠️ Two glass buttons side by side is two SECONDARY buttons. These two doors
   were added to a hero that had none at all; they do not get to dissolve back
   into the picture now. The primary is bright, the secondary is dark: a
   stranger can tell them apart without reading either. */
.lanaihero .btn{
  background:color-mix(in srgb, var(--clearcoat) 84%, transparent);
  border:1px solid color-mix(in srgb, var(--clearcoat) 86%, #fff);
  color:var(--clearcoat-ink);
}
.lanaihero .btn:hover{
  background:color-mix(in srgb, var(--clearcoat-hi) 92%, transparent);
  border-color:#fff;
}
/* SECONDARY — clearer glass. ⛔ .68 and not lower: at .62 white type measured
   5.0:1 against a white sky, which is a floor nobody should ship on. */
.lanaihero .btn--ghost{
  background:rgba(6,19,34,.68);
  border:1px solid rgba(255,255,255,.55);
  color:#fff;
}
.lanaihero .btn--ghost:hover{background:rgba(6,19,34,.80);border-color:#fff}
/* ⭐ depth from a hairline and a blur, never a drop shadow, and a real
   :focus-visible ring that is visible on BOTH glasses. */
.lanaihero .btn:focus-visible{
  outline:2px solid #fff; outline-offset:3px;
  box-shadow:0 0 0 5px rgba(6,19,34,.75);
}
