:root{
  --bone:#F4F2EC;--paper:#FBFAF6;--ink:#131313;--void:#0B0B0B;
  --cobalt:#005BFF;--cobalt-700:#0048CC;/* round-g cobalt fold 2026-07-27: canonical cobalt-dark (~0.8x --cobalt on hue line); retired stray --cobalt-d #0a4fd8 */--white:#FFFFFF;--soft:#EDEBE3;--red:#C0392B;--ok:#1F9D55;--warn:#C77D0A;/* round-f: foundation absorbs shop-invented semantics */--acid:#B6FF00;--amber:#FFB000;
  --line:#DAD7CC;--line-2:#CBC9BF;--mut:#6B6759;--ink-2:#161616;--line-dark:#2A2A2A;
  
  --mx:clamp(20px,5vw,80px);--maxw:1560px;--headh:68px;--headbd:1.5px;
  --disp:"FH Lecturis","Helvetica Neue",Impact,sans-serif;
  --grot:"Neue Haas Grotesk Display","Helvetica Neue",Arial,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --sans:"Neue Haas Grotesk Text","Helvetica Neue",Arial,sans-serif;
}
*{box-sizing:border-box;}
html{background:linear-gradient(var(--bone) 0 50%,var(--void) 50% 100%);}
body{margin:0;background:var(--bone);color:var(--ink);font-family:var(--sans);overflow-x:clip;-webkit-font-smoothing:antialiased;}
img{display:block;max-width:100%;}
a{color:inherit;text-decoration:none;}
::selection{background:var(--cobalt);color:#fff;}
.wrap{max-width:var(--maxw);margin:0 auto;padding-inline:var(--mx);}
.ey{font-family:var(--mono);font-size:11px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--mut);}
.rule{height:2px;background:var(--ink);border:0;}
.hair{height:1px;background:var(--line);border:0;}
.sig-word{color:var(--cobalt);}
.ff-plate{position:absolute;inset:0;width:100%;height:100%;background:#15140f;display:block;z-index:0;}
.ff-plate.light{background:var(--bone);}
image-slot{display:block;background:#15140f;}
html.gn2-rev [data-reveal]{opacity:0;transform:translateY(20px);}
html.gn2-rev [data-reveal].in{opacity:1;transform:none;transition:opacity .7s cubic-bezier(.2,.7,.2,1) var(--d,0ms),transform .7s cubic-bezier(.2,.7,.2,1) var(--d,0ms);}
html.gn2-rev .ff-mast .ln{transform:scaleX(0);transform-origin:left;transition:transform .8s cubic-bezier(.2,.7,.2,1) .1s;}
.ff-mast.in .ln{transform:scaleX(1);}
@media (prefers-reduced-motion:reduce){[data-reveal]{opacity:1 !important;transform:none !important;}.ff-mast .ln{transform:scaleX(1) !important;}}
.qc{position:relative;display:inline-flex;align-items:center;gap:12px;height:56px;padding:0 26px;border:1.6px solid var(--ink);background:var(--paper);color:var(--ink);font-family:var(--mono);font-weight:700;font-size:13px;letter-spacing:.06em;text-transform:uppercase;cursor:pointer;user-select:none;white-space:nowrap;transform:translateY(calc(var(--lift,0) * -1px));box-shadow:var(--sox,0px) var(--soy,0px) var(--sblur,0px) rgba(19,19,19,var(--sop,0));transition:box-shadow .22s ease, transform .14s ease, border-color .18s ease;}
.qc .lbl,.qc .arwrap{position:relative;z-index:3;}
.qc .arwrap{display:inline-block;transition:transform .16s cubic-bezier(.2,.8,.3,1);}
.qc:hover .arwrap,.qc:focus-visible .arwrap{transform:translateX(2px);}
.qc.accent{background:var(--cobalt);color:#fff;border-color:var(--cobalt);}
.qc.on-void{background:var(--void);color:#fff;border-color:var(--line-dark);}
.qc::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;opacity:0;transition:opacity .2s ease;background:radial-gradient(90px 60px at var(--hx,50%) var(--hy,40%), rgba(255,255,255,.5), transparent 70%);}
.qc.accent::after{background:radial-gradient(110px 70px at var(--hx,50%) var(--hy,40%), rgba(255,255,255,.22), transparent 72%);}
.qc:hover::after,.qc:focus-visible::after{opacity:1;}
.qc.press{transform:translateY(1px) !important;box-shadow:0 1.5px 3px rgba(19,19,19,.3) !important;transition:box-shadow .09s ease, transform .07s ease;}
.qc::before{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;opacity:0;box-shadow:inset 0 0 0 2px rgba(19,19,19,.25), inset 0 2px 6px rgba(19,19,19,.2);}
.qc.accent::before,.qc.on-void::before{box-shadow:inset 0 0 0 2px rgba(255,255,255,.28), inset 0 2px 6px rgba(0,0,0,.5);}
.qc.printed::before{animation:qcPrint .12s ease-out 1;}
@keyframes qcPrint{0%{opacity:0;}30%{opacity:1;}100%{opacity:0;}}
.qc:focus-visible{outline:none;border-color:#000;box-shadow:0 3px 10px rgba(19,19,19,.16);}
.qc-lite{position:relative;display:inline-flex;align-items:center;gap:9px;height:48px;padding:0 4px;white-space:nowrap;flex-shrink:0;font-family:var(--mono);font-weight:700;font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink);cursor:pointer;background:none;border:0;transition:color .16s ease, transform .1s ease;}
.qc-lite::before{content:"";position:absolute;left:0;right:0;bottom:8px;height:1.5px;background:var(--cobalt);transform:scaleX(0);transform-origin:var(--org,left);transition:transform .2s cubic-bezier(.3,.7,.3,1);}
.qc-lite .arw{transition:transform .18s cubic-bezier(.2,.7,.2,1);}
.qc-lite:hover,.qc-lite:focus-visible{color:var(--cobalt);}
.qc-lite:hover::before,.qc-lite:focus-visible::before{transform:scaleX(1);}
.qc-lite:hover .arw,.qc-lite:focus-visible .arw{transform:translateX(2px);}
.on-void .qc-lite,.dark .qc-lite,.cta-band .qc-lite{color:#fff;}
.on-void .qc-lite::before,.dark .qc-lite::before,.cta-band .qc-lite::before{background:var(--acid);}
@media (prefers-reduced-motion:reduce){.qc{transition:none;box-shadow:none !important;transform:none !important;}.qc:hover,.qc:focus-visible{box-shadow:0 3px 8px rgba(19,19,19,.15) !important;}}
.ff-sec{position:relative;padding-block:clamp(64px,9vw,140px);}
.ff-sec.pad-sm{padding-block:clamp(48px,6vw,90px);}
.ff-sec.dark{background:var(--void);color:#fff;}
.ff-sec.cobalt{background:var(--cobalt);color:#fff;}
.ff-mast{display:flex;align-items:center;gap:14px;font-family:var(--mono);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--mut);margin-bottom:26px;}
.ff-mast .idx{color:var(--ink);}
.dark .ff-mast .idx,.cobalt .ff-mast .idx,.ff-develop .ff-mast .idx{color:#fff;}
.ff-mast .ln{flex:1;height:1px;background:var(--line);}
.dark .ff-mast .ln{background:var(--line-dark);}
.cobalt .ff-mast,.ff-develop .ff-mast{color:rgba(255,255,255,.92);}.cobalt .ff-mast .ln,.ff-develop .ff-mast .ln{background:rgba(255,255,255,.42);}
.ff-h2{font-family:var(--grot);font-weight:900;text-transform:uppercase;line-height:.9;letter-spacing:-.03em;font-size:clamp(38px,5.4vw,78px);margin:0;overflow-wrap:break-word;}
.ff-sec.dark .ff-h2{color:#fff;}
.ff-sig-head{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:30px;align-items:end;margin-bottom:clamp(30px,4vw,56px);}
.ff-sig-head p{max-width:46ch;font-size:16px;line-height:1.55;color:#3a3a3a;margin:0;}
.ff-sec.dark .ff-sig-head p,.pg-sec.dark .ff-sig-head p{color:rgba(255,255,255,.72);}
@media (max-width:1080px){.ff-sig-head{grid-template-columns:minmax(0,1fr);}}
body{--headh:68px;}
.pg-hero{position:relative;padding:calc(var(--headh) + clamp(54px,9vw,120px)) 0 clamp(40px,6vw,80px);background:var(--bone);color:var(--ink);overflow:hidden;}
.pg-hero.dark{background:var(--void);color:#fff;}
.pg-hero .wrap{position:relative;z-index:2;}
.pg-hero-top{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;font-family:var(--mono);font-size:10.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--mut);border-bottom:1px solid var(--line);padding-bottom:14px;margin-bottom:clamp(26px,5vw,60px);}
.pg-hero.dark .pg-hero-top{color:rgba(255,255,255,.62);border-color:rgba(255,255,255,.18);}
.pg-eye{display:inline-flex;align-items:center;gap:9px;font-family:var(--mono);font-size:12px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--cobalt);margin:0 0 clamp(16px,2.5vw,26px);}
.pg-eye i{width:8px;height:8px;background:var(--cobalt);border-radius:1px;}
.pg-hero.dark .pg-eye{color:var(--acid);}
.pg-hero.dark .pg-eye i{background:var(--acid);box-shadow:0 0 10px var(--acid);}
.pg-hero .pg-word{font-family:var(--disp);font-weight:700;text-transform:uppercase;line-height:.82;letter-spacing:-.045em;font-size:clamp(78px,17vw,260px);margin:0 0 0 -.04em;}
.pg-hero .pg-word.two{font-size:clamp(56px,11.5vw,178px);}
/* WO-013: compact hero modifier (design round b, subpage.css) — no consumer on staging yet; Cart wiring is Claude Design B6 */
.pg-hero.compact{padding:calc(var(--headh) + clamp(24px,3.5vw,48px)) 0 clamp(22px,3vw,36px);}.pg-hero.compact .pg-word{font-size:clamp(40px,7vw,92px);}.pg-hero.compact .pg-hero-top{margin-bottom:clamp(18px,3vw,32px);}
.pg-hero.dark .pg-word{color:#fff;}
.pg-word .dot{color:var(--cobalt);}
.pg-hero.dark .pg-word .dot{color:var(--acid);}
.pg-poem{max-width:30ch;margin:clamp(20px,3vw,32px) 0 0;font-family:var(--grot);font-weight:900;text-transform:uppercase;line-height:.98;letter-spacing:-.02em;font-size:clamp(22px,3vw,40px);}
.pg-hero.dark .pg-poem{color:#fff;}
.pg-support{max-width:52ch;margin:18px 0 0;font-size:clamp(15px,1.5vw,18px);line-height:1.55;color:#3a3a38;}
.pg-hero.dark .pg-support{color:rgba(255,255,255,.72);}
.pg-hero-cta{display:flex;flex-wrap:wrap;gap:14px 20px;align-items:center;margin-top:clamp(26px,4vw,40px);}
.pg-hero-furn{display:flex;flex-wrap:wrap;gap:8px 24px;margin-top:clamp(26px,4vw,40px);padding-top:16px;border-top:1px solid var(--line);}
.pg-hero.dark .pg-hero-furn{border-color:rgba(255,255,255,.2);}
.pg-hero-furn span{font-family:var(--mono);font-size:10.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--mut);}
.pg-hero.dark .pg-hero-furn span{color:rgba(255,255,255,.6);}
.pg-hero-furn b{color:var(--ink);}.pg-hero.dark .pg-hero-furn b{color:#fff;}
.pg-hero .pg-hero-media{position:absolute;inset:0;z-index:0;}
.pg-hero .pg-hero-media .scrim{position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(11,11,11,.5),rgba(11,11,11,.34) 40%,rgba(11,11,11,.72));}
.pg-hero.dark .qc{background:rgba(251,250,246,.06);color:#fff;border-color:rgba(255,255,255,.5);}
.pg-hero.dark .qc.accent{background:var(--cobalt);color:#fff;border-color:var(--cobalt);}
.pg-hero.dark .qc-lite{color:#fff;}.pg-hero.dark .qc-lite::before{background:var(--cobalt);}
.shop-bento{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:minmax(178px,1fr);gap:10px;}
.bento-tile{position:relative;overflow:hidden;background:#15140f;border:1.5px solid var(--line);display:flex;flex-direction:column;justify-content:flex-end;min-height:178px;text-decoration:none;isolation:isolate;}
.bento-tile .ff-plate{transition:transform .6s cubic-bezier(.2,.7,.2,1);}
.bento-tile .scrim{position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(11,11,11,.14),rgba(11,11,11,.1) 40%,rgba(11,11,11,.84));}
.bento-tile .bt-in{position:relative;z-index:2;padding:clamp(15px,1.5vw,24px);}
.bento-tile .bt-idx{font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.14em;color:#8ab4ff;}
.bento-tile h3{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.02em;line-height:.9;color:#fff;margin:7px 0 0;font-size:clamp(19px,1.9vw,28px);}
.bento-tile p{color:rgba(255,255,255,.8);font-size:13.5px;line-height:1.5;margin:9px 0 0;max-width:34ch;}
.bento-tile .bt-go{font-family:var(--mono);font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:#fff;margin-top:14px;display:inline-flex;gap:8px;align-items:center;transition:color .2s;white-space:nowrap;}
.bento-tile.feat{grid-column:span 2;grid-row:span 2;}.bento-tile.feat h3{font-size:clamp(34px,4vw,58px);}
.bento-tile.wide{grid-column:span 2;}
@media(hover:hover){.bento-tile:hover .ff-plate{transform:scale(1.055);}.bento-tile:hover .bt-go{color:#8ab4ff;}.bento-tile:hover .bt-go span{transform:translateX(3px);}}
.bento-tile .bt-go span{transition:transform .2s;}
@media(max-width:860px){.shop-bento{grid-template-columns:repeat(2,1fr);}.bento-tile.feat{grid-column:span 2;grid-row:span 1;}.bento-tile.wide{grid-column:span 2;}}
@media(max-width:520px){.shop-bento{grid-template-columns:1fr;}.bento-tile,.bento-tile.feat,.bento-tile.wide{grid-column:span 1;grid-row:span 1;}}
.bento-tile.b-cobalt{background:#005BFF;border-color:#005BFF;}.bento-tile.b-cobalt .bt-idx{color:rgba(255,255,255,.72);}
.bento-tile.b-ink{background:#131313;border-color:#131313;}.bento-tile.b-ink .bt-idx{color:#8ab4ff;}
.bento-tile.b-paper{background:var(--bone);border-color:var(--line);}.bento-tile.b-paper h3{color:#131313;}.bento-tile.b-paper p{color:#3a3a38;}.bento-tile.b-paper .bt-idx{color:#005BFF;}.bento-tile.b-paper .bt-go{color:#131313;}
.media-band{position:relative;height:clamp(340px,54vw,640px);overflow:hidden;background:#15140f;}
.media-band .cap{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:clamp(20px,3vw,40px);display:flex;justify-content:space-between;align-items:flex-end;gap:16px;flex-wrap:wrap;background:linear-gradient(180deg,transparent,rgba(11,11,11,.72));color:#fff;}
.media-band .cap .t{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.02em;line-height:.95;font-size:clamp(22px,3vw,40px);max-width:20ch;}
.media-band .cap .m{font-family:var(--mono);font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--acid);white-space:nowrap;text-align:right;}
.media-band .cap .m.cobalt{color:#8ab4ff;}
.media-split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,3vw,52px);align-items:center;}
.media-split.flip .ms-media{order:2;}
.media-split .ms-media{position:relative;aspect-ratio:4/3;overflow:hidden;background:#15140f;border:1.5px solid var(--line);}
.media-split.on-dark .ms-media{border-color:var(--line-dark);}
.media-split .ms-media .tag{position:absolute;top:12px;left:12px;z-index:2;font-family:var(--mono);font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#fff;background:rgba(11,11,11,.6);padding:5px 9px;}
.media-split .ms-text h3{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.02em;line-height:1;font-size:clamp(24px,3vw,40px);margin:0 0 14px;}
.media-split .ms-text p{font-size:15.5px;line-height:1.65;color:#3a3a38;margin:0 0 14px;max-width:44ch;}
.pg-sec.dark .media-split .ms-text p{color:rgba(255,255,255,.74);}
@media(max-width:760px){.media-split{grid-template-columns:1fr;}.media-split.flip .ms-media{order:0;}}
.media-mosaic{display:grid;grid-template-columns:repeat(4,1fr);gap:1.5px;background:var(--line);border:1.5px solid var(--line);}
.media-mosaic .cell{position:relative;aspect-ratio:1/1;overflow:hidden;background:#15140f;}
.media-mosaic .cell.wide{grid-column:span 2;aspect-ratio:2/1;}
.media-mosaic .cell.tall{grid-row:span 2;aspect-ratio:1/2;}
.media-mosaic .cell .tag{position:absolute;bottom:8px;left:8px;z-index:2;font-family:var(--mono);font-size:9px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#fff;background:rgba(11,11,11,.55);padding:4px 7px;}
@media(max-width:640px){.media-mosaic{grid-template-columns:repeat(2,1fr);}.media-mosaic .cell.wide{grid-column:span 2;}.media-mosaic .cell.tall{grid-row:span 1;aspect-ratio:1/1;}}
.fig{border:1.5px solid var(--line);background:#15140f;position:relative;overflow:hidden;aspect-ratio:16/9;}
.fig .cap{position:absolute;bottom:0;left:0;right:0;z-index:2;padding:12px 14px;background:linear-gradient(180deg,transparent,rgba(11,11,11,.7));color:#fff;font-family:var(--mono);font-size:10.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;}
.pg-lead{display:grid;grid-template-columns:1.15fr 1fr;gap:clamp(22px,4vw,64px);align-items:end;margin-bottom:clamp(28px,4vw,52px);}
.pg-lead p{margin:0;font-size:clamp(15px,1.5vw,18px);line-height:1.6;color:#3a3a38;}
.pg-sec.dark .pg-lead p{color:rgba(255,255,255,.72);}
.pg-prose{max-width:64ch;}
.pg-prose p{font-size:16px;line-height:1.68;color:#33322f;margin:0 0 18px;}
.pg-sec.dark .pg-prose p{color:rgba(255,255,255,.76);}
.pg-prose p b{color:var(--ink);}.pg-sec.dark .pg-prose p b{color:#fff;}
.pg-prose h3{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.02em;line-height:.98;font-size:clamp(22px,2.4vw,30px);margin:34px 0 12px;}
.pg-cards{display:flex;flex-wrap:wrap;gap:1.5px;background:var(--line);border:1.5px solid var(--line);}
.pg-cards>*{flex:1 1 260px;min-width:0;}
.pg-card{background:var(--paper);padding:clamp(22px,2.4vw,32px);display:flex;flex-direction:column;gap:10px;position:relative;transition:background .18s ease;}
.pg-card:hover{background:var(--bone);}
.pg-card .c-idx{font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.14em;color:var(--cobalt);}
.pg-card h3{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.02em;line-height:.98;font-size:clamp(20px,2vw,26px);margin:2px 0 4px;}
.pg-card p{margin:0;font-size:14px;line-height:1.55;color:#4a4a46;flex:1;}
.pg-card .c-go{font-family:var(--mono);font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink);margin-top:8px;}
.pg-card:hover .c-go{color:var(--cobalt);}
.faq-group{margin-bottom:clamp(34px,5vw,60px);}
.faq-group > h3{font-family:var(--mono);font-size:12px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--cobalt);margin:0 0 6px;padding-bottom:12px;border-bottom:1.5px solid var(--ink);}
.faq-item{border-bottom:1.5px solid var(--line);}
.faq-q:is(main[data-nav] *,.woocommerce-page *):is(main[data-nav] *,.woocommerce-page *){width:100%;background:none;border:0;cursor:pointer;text-align:left;display:flex;justify-content:space-between;align-items:baseline;gap:20px;padding:20px 0;font-family:var(--grot);font-weight:700;letter-spacing:-.01em;font-size:clamp(17px,1.7vw,21px);color:var(--ink);line-height:1.2;}
.faq-q .fq-sign{font-family:var(--mono);font-size:20px;color:var(--cobalt);flex:none;transition:transform .2s ease;}
.faq-item.open .fq-sign{transform:rotate(45deg);}
.faq-a{max-height:0;overflow:hidden;transition:max-height .3s ease;}
.faq-a-in{padding:0 0 22px;max-width:70ch;font-size:15px;line-height:1.62;color:#4a4a46;}
.faq-a-in p{margin:0 0 12px;}.faq-a-in p:last-child{margin:0;}
.addr-card{border:1.6px solid var(--ink);background:var(--paper);}
.addr-card .ac-bar{display:flex;justify-content:space-between;align-items:center;gap:12px;background:var(--ink);color:#fff;padding:12px 18px;font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;}
.addr-card .ac-bar .dot{width:8px;height:8px;background:var(--acid);border-radius:50%;box-shadow:0 0 8px var(--acid);}
.addr-card .ac-body{padding:clamp(22px,3vw,36px);}
.addr-card .ac-line{font-family:var(--mono);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--mut);margin-bottom:14px;}
.addr-card .ac-addr{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.02em;line-height:1.0;font-size:clamp(28px,4vw,52px);margin:0;}
.addr-card .ac-sub{margin:16px 0 0;font-size:15px;line-height:1.55;color:#4a4a46;}
.addr-card .ac-meta{display:flex;flex-wrap:wrap;gap:8px 28px;margin-top:20px;padding-top:18px;border-top:1px solid var(--line);font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--mut);}
.loc-grid{display:flex;flex-wrap:wrap;gap:1.5px;background:var(--line);border:1.5px solid var(--line);}
.loc-grid>*{flex:1 1 280px;min-width:0;}
.loc{background:var(--paper);padding:clamp(20px,2.4vw,30px);}
.loc.hq{background:var(--ink);color:#fff;flex:2 1 560px;}
.loc .l-tag{font-family:var(--mono);font-size:10.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--cobalt);}
.loc.hq .l-tag{color:var(--acid);}
.loc h3{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.02em;line-height:1;font-size:clamp(20px,2.2vw,30px);margin:8px 0 8px;}
.loc p{margin:0;font-size:14px;line-height:1.55;color:#4a4a46;}.loc.hq p{color:rgba(255,255,255,.72);}
.loc .l-meta{margin-top:14px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--mut);}
.loc.hq .l-meta{color:rgba(255,255,255,.6);}
@media(max-width:640px){.loc.hq{flex:1 1 280px;}}
.spec-rows{border-top:1.5px solid var(--ink);}
.spec-row{display:grid;grid-template-columns:1fr auto;gap:20px;align-items:baseline;padding:18px 0;border-bottom:1.5px solid var(--line);}
.spec-row .sr-k{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.01em;font-size:clamp(18px,2vw,24px);}
.spec-row .sr-v{font-family:var(--mono);font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--cobalt);}
.pg-sec.dark .spec-rows{border-color:rgba(255,255,255,.35);}
.pg-sec.dark .spec-row{border-color:rgba(255,255,255,.16);}
.pg-sec.dark .spec-row .sr-v{color:var(--acid);}
.tline{display:grid;gap:0;border-top:1.5px solid rgba(255,255,255,.3);}
.tstep{display:grid;grid-template-columns:64px 1fr;gap:clamp(14px,2vw,28px);padding:clamp(20px,2.6vw,32px) 0;border-bottom:1.5px solid rgba(255,255,255,.16);}
.tstep .t-n{font-family:var(--disp);font-size:clamp(34px,4vw,56px);line-height:.8;color:var(--acid);}
.tstep h3{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.02em;line-height:1;font-size:clamp(20px,2.2vw,28px);margin:0 0 8px;color:#fff;}
.tstep p{margin:0;font-size:14.5px;line-height:1.55;color:rgba(255,255,255,.72);max-width:52ch;}
.tline.light{border-top-color:var(--ink);}
.tline.light .tstep{border-bottom-color:var(--line);}
.tline.light .t-n{color:var(--cobalt);}
.tline.light h3{color:var(--ink);}
.tline.light p{color:#4a4a46;}
.callout{border:1.6px solid var(--cobalt);background:var(--paper);padding:clamp(22px,3vw,34px);}
.callout.on-void{background:rgba(182,255,0,.06);border-color:var(--acid);}
.callout .co-k{font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--cobalt);margin-bottom:10px;}
.callout.on-void .co-k{color:var(--acid);}
.callout p{margin:0;font-family:var(--grot);font-weight:700;letter-spacing:-.01em;line-height:1.1;font-size:clamp(20px,2.6vw,32px);}
.callout.on-void p{color:#fff;}
.callout .co-sub{font-family:var(--sans);font-weight:400;font-size:15px;line-height:1.55;color:#4a4a46;margin-top:12px;}
.callout.on-void .co-sub{color:rgba(255,255,255,.72);}
.shop-toolbar{display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between;padding-bottom:16px;border-bottom:1.5px solid var(--ink);margin-bottom:clamp(20px,3vw,32px);}
.shop-filters{display:flex;flex-wrap:wrap;gap:8px;}
.shop-chip{font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:8px 14px;border:1.4px solid var(--line);cursor:pointer;color:var(--ink);background:var(--paper);transition:all .15s ease;}
.shop-chip:hover{border-color:var(--ink);}
.shop-chip.on{background:var(--ink);color:#fff;border-color:var(--ink);}
.shop-count{font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--mut);}
.prod-grid{display:flex;flex-wrap:wrap;gap:1.5px;background:var(--line);border:1.5px solid var(--line);}
.prod-grid>*{flex:1 1 240px;min-width:0;}
.prod-card{background:var(--paper);display:flex;flex-direction:column;transition:background .16s ease;}
.prod-card:hover{background:#fff;}
.prod-media{position:relative;aspect-ratio:1/1;overflow:hidden;background:var(--bone);}
.prod-badge{position:absolute;top:10px;left:10px;font-family:var(--mono);font-size:9px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;padding:4px 7px;background:var(--cobalt);color:#fff;}
.prod-badge.out{background:var(--mut);}
.prod-info{padding:16px 16px 18px;display:flex;flex-direction:column;gap:4px;flex:1;}
.prod-info .p-brand{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--mut);}
.prod-info .p-name{font-family:var(--grot);font-weight:700;letter-spacing:-.01em;font-size:16px;line-height:1.05;margin:0;flex:1;}
.prod-info .p-foot{display:flex;justify-content:space-between;align-items:baseline;margin-top:10px;}
.prod-info .p-price{font-family:var(--grot);font-weight:900;font-size:18px;letter-spacing:-.02em;}
.prod-info .p-add{font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--cobalt);}
.cta-band{background:var(--void);color:#fff;padding:clamp(48px,8vw,110px) 0;text-align:left;}
.cta-band .cb-eye{font-family:var(--mono);font-size:12px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--acid);display:inline-flex;align-items:center;gap:9px;margin:0 0 18px;}
.cta-band .cb-eye i{width:8px;height:8px;background:var(--acid);border-radius:1px;box-shadow:0 0 10px var(--acid);}
.cta-band h2{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.03em;line-height:.9;font-size:clamp(40px,7vw,104px);margin:0 0 20px;}
.cta-band p{max-width:52ch;font-size:clamp(15px,1.6vw,19px);line-height:1.5;color:rgba(255,255,255,.72);margin:0 0 30px;}
.cta-band .cb-cta{display:flex;flex-wrap:wrap;gap:14px 20px;align-items:center;}
.empty{border:1.6px dashed var(--line);padding:clamp(34px,6vw,72px);text-align:center;}
.empty .e-k{font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--cobalt);margin-bottom:14px;}
.empty h3{font-family:var(--grot);font-weight:900;text-transform:uppercase;letter-spacing:-.02em;line-height:1;font-size:clamp(24px,3.4vw,44px);margin:0 0 12px;}
.empty p{max-width:46ch;margin:0 auto;font-size:15px;line-height:1.55;color:#4a4a46;}
@media(max-width:820px){.pg-lead{grid-template-columns:1fr;align-items:start;}}
main[data-nav]{font-family:var(--sans);color:var(--ink);}
main[data-nav] :is(h1,h2,h3,h4,h5,h6){color:inherit !important;font-family:var(--grot) !important;}
/* Component colour contracts must survive the broad Elementor heading reset above. */
main[data-nav] .bento-tile h3{color:#fff !important;}
main[data-nav] .bento-tile.b-paper h3{color:var(--ink) !important;}
main[data-nav] .pg-word,main[data-nav] .cta-word{font-family:var(--disp) !important;font-weight:700 !important;}
main[data-nav] .ff-hero h1{font-family:var(--disp) !important;}
/* ^ display-type rescue for a BARE .ff-hero h1 — homepage "DEVELOPED.", NERD "NERD." (.ns-mark),
   Why Our Lab "STANDARD.". The design declares font-family:var(--disp) for all three, but they carry
   no .pg-word/.cta-word class, so the main[data-nav] :is(h1..h6) grot override wins without this.
   NOTE for future rescues: a coded page's own CSS often ships INSIDE its Elementor widget as an
   inline <style> in the BODY, which cascades AFTER this file in the head — so at EQUAL specificity
   the widget wins. A foundation rescue that must beat a widget-declared property needs HIGHER
   specificity (see `.nl-panel .nl-cmp`) or !important, not merely a later rule in this file. */
main[data-nav] .tstep .t-n,main[data-nav] .ob-head .s-n{font-family:var(--disp) !important;}
/* Round-9 header flow restoration. The design's .ff-head is a direct <body> child using
   position:sticky, so it occupies --headh + its border of normal flow. In Elementor the
   header is nested (every ancestor is header-height), which makes sticky unable to pin —
   so #ffHead stays position:fixed (pinning + full-bleed + gn2-chrome's smart-header all
   depend on it) and this reserves the equivalent flow on the header wrapper instead.
   Derived from the same tokens the header itself uses, so the two cannot drift. */
header.elementor-location-header{height:calc(var(--headh) + var(--headbd));}

/* WO-011 (round 3): the design now defines this range itself, so the Round-13 stopgap retires.
   fullframe.css gained `.ff-h2{overflow-wrap:break-word}` + `@media(max-width:420px){font-size:
   clamp(28px,8.5vw,40px)}` — a lower floor than Round-13's 31px AND the word-breaking Round-13
   deliberately withheld. Design overrules the local judgement per the fidelity rule; the new floor
   is strictly more aggressive at every width Round-13 covered, so nothing it protected regresses. */
@media (max-width: 420px) {
  .ff-h2 { font-size: clamp(28px, 8.5vw, 40px); }
}

/* Round-13: FAQ questions must wrap. .faq-q is a <button>, and reset.css sets
   `[type="button"], [type="submit"], button { white-space: nowrap }` — so the question text was
   forced onto one line and pushed the trailing .fq-sign past the viewport (NERD +47px at 320).
   Neither the design nor our .faq-q rule declares white-space; this only neutralises the inherited
   reset. Containment fix, no type or layout change. */
.faq-q:is(main[data-nav] *,.woocommerce-page *):is(main[data-nav] *,.woocommerce-page *) { white-space: normal; }

/* Round-16: NERD loop containment. .nl-stage is a grid item of .nl-track and .nd are flex items of
   .nl-nodes; all default to min-width:auto, so they refuse to shrink below min-content and pushed
   304px of rail into a correct 280px track (+9px doc overflow at 320). This is the flexbox/grid twin
   of the minmax(0,1fr) fix — supplying behaviour for a width the design never drew, not overriding a
   design decision. .nd is a 2px rail with no text, so compressing it loses nothing.
   The loop's base rules live inline in the 109128 widget (Cowork's layer); this rescue sits in the
   foundation so it survives a widget re-push and stays inert on every page without .nl-* markup. */
.nl-stage { min-width: 0; }
.nl-nodes { min-width: 0; }
.nl-nodes .nd { min-width: 0; }

/* Round-16 (cont.): the actual floor was .nl-cmp — the Regular-vs-Member comparison grid, declared
   `grid-template-columns:1fr 1fr` with no mobile override (identical in the design source). Its fr
   tracks carry an auto minimum, so the pair refused to shrink and pinned .nl-panels' min-content at
   ~302px inside a 280px track. minmax(0,1fr) is the same containment pattern used for .ff-sig-head
   and .gnb-days: identical rendering wherever the content fits, defined behaviour where the design
   drew no comp. Columns land ~139px (~103px content after the 18px padding); the longest unbreakable
   token is "Process", so the copy wraps instead of overflowing. Two columns are preserved — stacking
   would be a layout decision, which is Neil's, not a containment fix. */
.nl-panel .nl-cmp { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }   /* .nl-panel prefix: the widget's inline <style> sits in the body, so an equal-specificity foundation rule loses on source order */

/* Round-20: base .ff-hero, ported VERBATIM from the design's ui_kits/fullframe/fullframe.css.
   It was never carried into this file when fullframe.css + subpage.css were merged, so no shared
   .ff-hero existed at all. The homepage and Why Our Lab masked that by re-declaring it locally
   (post-109096.css page CSS, and .wol .wol-hero respectively); NERD had no local copy and so
   rendered a transparent hero on the cream page bg, with the header's .at-top white nav illegible
   over it, and without the -68px slide-under. Both of those override this by source order /
   specificity, so this restores the design for NERD without touching them. */
.ff-hero{position:relative;min-height:100vh;display:flex;flex-direction:column;justify-content:flex-end;background:var(--void);color:#fff;overflow:hidden;margin-top:-68px;}

/* =====================================================================================
   WO-006 (2026-07-22) — KIT-2537 FORM-CONTROL GUARD + BUTTON STUDY v3, single source.

   THE TRAP. Kit 2537 styles bare elements:
     `.elementor-kit-2537 button, …input[type=button], …input[type=submit]`      (0,1,1)
     `.elementor-kit-2537 input:not([type=button]):not([type=submit]), …textarea` (0,3,1)
   setting font-family Inter, font-weight 400, line-height, background-color #F4F2EC,
   color #0B0B0B and (on buttons) border-style/border-color. Every design-system control
   written as a bare class — `.gn-add`, `.faq-q`, `.gnb-day`, `.sh-clear`, `.fp-size` … — is
   (0,1,0) and therefore LOSES. That is the whole epidemic (WO-005 rescues, WO-006 sweep).

   THE GUARD IS TWO HALVES THAT ONLY WORK TOGETHER.

   (A) RAISE THE COMPONENTS. Every rule in gn2-base.css / gn-shop.css / booking.css whose
       SUBJECT is a form control now carries `:is(main[data-nav] *,.woocommerce-page *)` twice
       on its subject compound. Three deliberate choices:
       · SUFFIX, not ancestor prefix. `main[data-nav] .sh--seamless .gn-add` silently matches
         nothing, because `.sh--seamless` is on the main element ITSELF
         (`<main class="g2main sh sh--seamless" data-nav>`). The suffix asks only "is this
         control inside the 2.0 region", which is true either way.
       · TWICE. One boost (+0,1,1) clears the kit's BUTTON rule but not its INPUT rule (0,3,1);
         that one still beat `.sh-search input`+boost (0,2,2) and left the shop search field on
         Inter. Verified live, not assumed.
       · WHOLE SELECTOR LISTS, states and compounds together, so every component moves up by the
         same amount and its internal cascade is untouched (`.sh--seamless .gn-add` still
         outranks `.gn-add`). Specificity now decides against the kit, so PRINT ORDER NO LONGER
         MATTERS — including for the booking controls that used to survive on a (0,1,1) tie.

   (B) DECLARE THE FONT ON CONTROLS THAT INHERIT IT. (A) alone is not enough: booking's
       `.gnb-mnav button`, the drawer's `.sh-rail-head button` and `.sh-chip button` never
       declared a font-family — they inherited — and inheritance cannot beat an explicit
       `Inter`. Each now declares its own, in its own stylesheet.

   A BLANKET NEUTRALISER WAS BUILT, MEASURED AND REJECTED — do not re-add one. A rule at (0,1,2)
   (`main[data-nav] :is(button,input,select,textarea){font-family:inherit;background-color:transparent;…}`)
   sits above the kit and below the boosted components, which is exactly right on paper and passed
   a static longhand audit. Shipped to staging it broke three live surfaces: the 109127 login
   inputs and the 109197 gallery thumbs lost their paper background, and a 109142 order-builder
   button lost acid-on-mono. Cause: those components paint through the `background:` and `font:`
   SHORTHANDS at (0,1,1) from a page's own <style>, which no longhand audit can see and which a
   (0,1,2) rule outranks. The blanket shape cannot be made safe while any component CSS lives in a
   page's inline <style>. (`:not([class])` fails for the same reason — components are routinely
   styled through a class-less child: `.fp-thumbs button`, `.gnb-mnav button`.) Cascade layers
   cannot express "above the kit, below the components" while the kit is unlayered.

   ENUMERATED BEFORE SHIPPING — live walk of all 31 coded pages at 1440 AND 390 with JS-generated
   controls present (drawer opened, calendar day picked), 529 controls, computed-style before/after
   diff: qa/tools/form-control-inventory.mjs → qa/reports/_wo006/. Covered: .gn-add, .sh-filterbtn,
   .sh-rail-head button, .sh-search input, .sh-facet input, .sh-facet .more, .sh-chip button,
   .sh-clear, .sh-apply, .sh-reset, .sh-empty button, .sh-sort (109191/193/195) · .faq-q
   (109117/109128 — the kit's beige chip background was STILL live there after the WO-005 font-only
   rescue) · .gnb-day, .gnb-mnav button, .gnb-seg button, .gnb-slot (109130/109132) · .fp-size,
   .fp-sw (109197) · .est-qty input (109133).

   OUT OF SCOPE, still kit-styled and unchanged: WooCommerce-native controls (109136 account,
   109127 login inputs) and PPOM radios/checkboxes (109142) — no text, or Woo's own tier.

   RULE FOR NEW WORK: a <button>/<input>/<select>/<textarea> styled from a bare class must carry
   the subject boost, in the component's own stylesheet. An unscoped bare class looks right in the
   design file and renders Inter-on-beige on the site.
   ===================================================================================== */

/* Page-inline components. .fp-* (109197) and .est-qty (109133) declare their base look in the
   page's own <style>, which the foundation cannot re-scope from here — so the verified WO-005/006
   rescue values are relocated verbatim from those pages' custom_css to this one source. They stay
   !important because they must also outrank the page-inline states they duplicate. If the Frames
   or Archive component's design values change, change them HERE too (registry: form-control trap). */
.fp-size:is(main[data-nav] *,.woocommerce-page *){font-family:var(--fp-sans,var(--sans))!important;font-size:12px!important;font-weight:600!important;letter-spacing:.02em!important;background:var(--fp-paper,#FBFAF6)!important;color:var(--fp-ink,#131313)!important;border:1px solid var(--fp-line,#DAD8CF)!important;padding:11px 4px!important;min-height:44px!important}
.fp-size:hover:is(main[data-nav] *,.woocommerce-page *){border-color:var(--fp-ink,#131313)!important}
.fp-size[aria-pressed="true"]:is(main[data-nav] *,.woocommerce-page *){background:var(--fp-cobalt,#005BFF)!important;border-color:var(--fp-cobalt,#005BFF)!important;color:#fff!important}
.fp-sw:is(main[data-nav] *,.woocommerce-page *){padding:0!important;border:1px solid rgba(11,11,11,.18)!important}
.est-qty input:is(main[data-nav] *,.woocommerce-page *){font-family:var(--mono)!important;font-size:15px!important}

/* Button Study v3 — consolidated 2026-07-22 from the two inline layers this replaces:
   `gn20-btnv3` (snippet 109162's $css head; that snippet is now the Woo functional tier only and
   its handle is renamed gn2-woo-skin) and `gn2-button-refresh` (gn2-chrome.php's wp_head print,
   now removed). Both printed AFTER this file, so the block sits at the END of gn2-base.css to
   preserve the source order they relied on; the declarations stay !important because they must
   outrank kit 2537's (0,1,1) button rules on <button class="qc">. v3 = matte face (the ::after
   light patch is killed), mono 13/700 radius 0 pinned, contact-flip press colours. Only these
   properties are pinned — background/color/border-color are deliberately left free at rest so
   variants like `.pg-hero.dark .qc` still paint. `.qc` is also used on <a>, which the kit's button
   rule never touched; keeping these rules unscoped preserves that. */
.qc::after{display:none !important;}
.qc{position:relative !important;box-shadow:var(--sox,0px) var(--soy,0px) var(--sblur,0px) rgba(19,19,19,var(--sop,0)) !important;transition:box-shadow .22s ease,transform .14s ease !important;border-radius:0 !important;font-family:"IBM Plex Mono",ui-monospace,monospace !important;font-weight:700 !important;font-size:13px !important;letter-spacing:.06em !important;text-transform:uppercase !important;}
.qc.press{transform:translateY(1px) !important;box-shadow:0 1.5px 3px rgba(19,19,19,.3) !important;}
.qc.press,.qc.tapped,.qc:active{transition:box-shadow .09s ease, transform .07s ease, background-color .1s ease, color .1s ease, border-color .1s ease;background:var(--cobalt) !important;border-color:var(--cobalt) !important;color:#fff !important;}
.qc.press .lbl,.qc.tapped .lbl,.qc:active .lbl,.qc.press .arw,.qc.tapped .arw,.qc:active .arw,.qc.press .arwrap,.qc:active .arwrap{color:#fff !important;}
.qc.accent.press,.qc.accent.tapped,.qc.accent:active{background:#FBFAF6 !important;border-color:#FBFAF6 !important;color:var(--cobalt) !important;}
.qc.accent.press .lbl,.qc.accent.tapped .lbl,.qc.accent:active .lbl,.qc.accent.press .arw,.qc.accent:active .arw,.qc.accent.press .arwrap,.qc.accent:active .arwrap{color:var(--cobalt) !important;}
.qc.on-void.press,.qc.on-void.tapped,.qc.on-void:active{background:#B6FF00 !important;border-color:#B6FF00 !important;color:var(--ink) !important;}
.qc.on-void.press .lbl,.qc.on-void:active .lbl,.qc.on-void.press .arw,.qc.on-void:active .arw,.qc.on-void.press .arwrap,.qc.on-void:active .arwrap{color:var(--ink) !important;}
.qc-lite{font-family:"IBM Plex Mono",ui-monospace,monospace !important;font-weight:700 !important;font-size:12px !important;letter-spacing:.06em !important;text-transform:uppercase !important;}

/* Carried over with the same layer (they rode in gn20-btnv3's $css, not because they are buttons —
   keeping them together preserves the exact cascade those pages render today). The svh line must
   stay AFTER the vh line: it is the progressive-enhancement override, not a duplicate. */
.ff-hero{min-height:calc(100vh + 68px) !important;}
.ff-hero{min-height:calc(100svh + 68px) !important;}
.ff-develop .ff-route .rt-t{color:#fff !important;}
.ff-develop .ff-route .rt-cta{color:#fff !important;}
/* change 2026-07-30 (staging change package): cobalt text contrast — route copy white .92 (>= AA 4.5:1 on cobalt, ~4.74) + order-first rt-n / rt-sep (02 divider) styling */
.cobalt .ff-route .rt-d,.ff-develop .ff-route .rt-d{color:rgba(255,255,255,.92) !important;}
.cobalt .ff-route .rt-n,.ff-develop .ff-route .rt-n{color:rgba(255,255,255,.92);}
.ff-route .rt-n{display:block;font-family:var(--mono);font-size:10.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;margin-bottom:8px;}
.rt-sep{margin:0;background:var(--cobalt-700);color:rgba(255,255,255,.92);font-family:var(--mono);font-size:10.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;padding:11px 22px;}

/* =====================================================================================
   WO-008 (2026-07-23) — Full Frame v4 round 2. Foundation deltas merged from the design
   source into this one file: fullframe.css lens + .pt gate + nav-flash CSS; subpage.css
   cobalt band + acid card. Verbatim from build-handoff/design-source (line-exact).
   ===================================================================================== */
/* fullframe.css 118-139 — .qc inverted-colour cursor disc (lens). */
/* ============================================================
   INVERTED-COLOUR CURSOR DISC — .qc lens (site-wide · promoted 2026-07-23)
   A solid hard-edged disc tracks the cursor over a .qc object and shows a
   colour-reversed clone of the button (fill ↔ text) inside it, while the
   Light-Cast directional shadow keeps casting underneath. fullframe.js clones
   each .qc into a .qc-lens overlay and toggles .lenson while the pointer is in.
   Reduced motion hides the lens entirely (Light-Cast press feedback remains).
   ============================================================ */
.qc-haslens{position:relative;overflow:hidden;}
.qc-lens{position:absolute!important;inset:0!important;margin:0!important;z-index:4!important;
  pointer-events:none;transform:none!important;box-shadow:none!important;border-color:transparent!important;
  opacity:0;transition:opacity .1s linear;
  -webkit-mask:radial-gradient(circle 60px at var(--lx,50%) var(--ly,50%),#000 0 59px,#0000 60px);
          mask:radial-gradient(circle 60px at var(--lx,50%) var(--ly,50%),#000 0 59px,#0000 60px);}
.qc-haslens.lenson .qc-lens{opacity:1;}
/* Elementor's generic `a:hover` may otherwise replace a signature button's resting foreground
   while the cursor disc is active. JS captures the correct pre-hover foreground per button, so
   cobalt, white, ink and acid variants all retain their own base label outside the inverted disc. */
.qc-haslens.lenson{color:var(--qc-rest-fg,inherit)!important;}
.qc-haslens.lenson>.lbl,.qc-haslens.lenson>.arwrap,.qc-haslens.lenson>.arwrap>.arw{color:inherit!important;}
/* lens fill/text are set inline by fullframe.js from the button's REAL computed
   colours (invert fill↔text) so page overrides — e.g. acid-card ink+acid CTAs —
   invert correctly instead of assuming the base .qc variant look. */
.qc-lens .lbl,.qc-lens .arw,.qc-lens .arwrap{color:inherit!important;}
.qc-lens::before,.qc-lens::after{display:none!important;}
@media(prefers-reduced-motion:reduce){.qc-lens{display:none!important;}.qc-haslens{overflow:visible;}}

/* fullframe.css 194 — cobalt-gate fix: dropdown link title rests on ink. Already live
   in the header widget's inline CSS; carried here as the foundation source of truth
   (it is the nav-flash gate — the flash below returns .pt to its resting colour). */
.ff-p-link .pt{font-family:var(--mono);font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink);}

/* fullframe.css 537-566 — NAV CONTACT-PRINT FLASH. Pending since 07-19, unblocked by
   the .pt gate; never deployed before. gn2-chrome.php toggles .ff-flash. */
/* ============================================================
   NAV CONTACT-PRINT FLASH · click / tap exposure cue (site-wide)
   pointerdown adds .ff-flash; chrome.js removes it on animationend.
   Top-bar links flash the cobalt public signal behind the type;
   dropdown + mobile-menu items expose to a photographic negative
   (ink field, bone type) that snaps then decays over ~180ms.
   Each animation ends on the element's NATURAL (non-hover) state so
   it hands back cleanly to hover / focus-within styling afterwards.
   Wrapped in prefers-reduced-motion: no-preference — reduced motion
   gets the instant :active / .tapped fallback only, no exposure.
   ============================================================ */
@media (prefers-reduced-motion:no-preference){
  /* top bar — cobalt signal wash behind the mono type (works on
     both the light header and the dark / at-top transparent header;
     background-only so it never fights the two-state text colour) */
  .ff-nav-link.ff-flash{animation:ffNavExpose .3s ease-out;}
  @keyframes ffNavExpose{0%,20%{background-color:rgba(0,91,255,.95);}100%{background-color:transparent;}}

  /* dropdown panel item — negative exposure: ink field, bone type */
  .ff-p-link.ff-flash{animation:ffPanelExpose .22s ease-out;}
  .ff-p-link.ff-flash .pt{animation:ffPtExpose .22s ease-out;}
  .ff-p-link.ff-flash .pd{animation:ffPdExpose .22s ease-out;}
  @keyframes ffPanelExpose{0%,34%{background:var(--ink);}100%{background:transparent;}}
  @keyframes ffPtExpose{0%,34%{color:var(--paper);}100%{color:var(--ink);}}
  @keyframes ffPdExpose{0%,34%{color:rgba(241,239,232,.62);}100%{color:var(--mut);}}

  /* mobile menu — same negative snap, full-bleed on the big actions */
  .ff-mm-actions a.ff-flash,.ff-mm-explore a.ff-flash{animation:ffMMExpose .24s ease-out;}
  @keyframes ffMMExpose{0%,34%{background:var(--ink);color:var(--paper);}100%{background:transparent;color:var(--ink);}}
}

/* subpage.css 366-394 — cobalt CTA band + acid card (Neil-approved 2026-07-23;
   acid-card = the adopted acid-on-light exception, one per page, card-scale). */
/* ---- cobalt CTA band — a page's ONE loud blue moment (route/CTA semantics) ---- */
.cta-band.cobalt{background:var(--cobalt);}
.cta-band.cobalt .cb-eye{color:#fff;}
.cta-band.cobalt .cb-eye i{background:#fff;box-shadow:none;}
.cta-band.cobalt .qc.accent{background:#fff;color:var(--cobalt);border-color:#fff;}
.cta-band.cobalt .qc.accent.press,.cta-band.cobalt .qc.accent.tapped,.cta-band.cobalt .qc.accent:active{background:var(--ink);border-color:var(--ink);color:#fff;}
.cta-band.cobalt .qc-lite::before{background:#fff;}

/* ---- acid CTA band — a page's ONE machine/process moment (electronic signal) ----
   subpage.css 373-386 (WO-011 round 3). Cobalt = you/route; ACID = the machine/process
   (develop · scan · process · self-serve · digitize). Full-bleed acid field, BLACK INK
   type only. One acid moment per page, never adjacent to a cobalt band. Lens + press
   feedback come from the shared .qc system. Live pages carrying it: 109130, 109133. */
.cta-band.acid{background:var(--acid);color:var(--ink);}
.cta-band.acid .cb-eye{color:var(--ink);}
.cta-band.acid .cb-eye i{background:var(--ink);box-shadow:none;}
.cta-band.acid h2{color:var(--ink);}
.cta-band.acid p{color:rgba(19,19,19,.74);}
.cta-band.acid .qc{border-color:var(--ink);color:var(--ink);}
.cta-band.acid .qc.accent{background:var(--ink);border-color:var(--ink);color:var(--acid);}
.cta-band.acid .qc.accent.press,.cta-band.acid .qc.accent.tapped,.cta-band.acid .qc.accent:active{background:#fff;border-color:#fff;color:var(--ink);}
.cta-band.acid .qc-lite::before{background:var(--ink);}
/* Live-only addition (no design counterpart needed): this file's line ~51 folds .cta-band into
   the `.on-void,.dark` group as `.cta-band .qc-lite{color:#fff}`, which the design does not have —
   there, .qc-lite simply inherits the band's colour and so goes ink on acid automatically. Without
   this the secondary links render white on acid green. The design pages paper over it with an
   inline color:var(--ink); pinning it here makes the band legible on its own. The hover pair is
   explicit for the same reason: at (0,3,0) it already outranks `.qc-lite:hover{color:var(--cobalt)}`,
   and stating it stops anyone "restoring" a cobalt hover *inside* the acid moment — which is the
   colour adjacency the protocol exists to prevent. The underline sweep stays the hover affordance,
   exactly as on the cobalt band. */
.cta-band.acid .qc-lite{color:var(--ink);}
.cta-band.acid .qc-lite:hover,.cta-band.acid .qc-lite:focus-visible{color:var(--ink);}

/* ---- acid card — transactional / electronic moment on light pages ----
   login, member pricing, order status. One per page, card-scale only —
   never a page colour, never adjacent to a cobalt band. */
.acid-card{display:flex;align-items:center;justify-content:space-between;gap:16px 30px;flex-wrap:wrap;background:var(--acid);color:var(--ink);border-radius:4px;padding:16px 20px;}
.acid-card .ac-l{min-width:0;flex:1 1 300px;}
.acid-card .ac-k{font-family:var(--mono);font-size:10.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--ink);display:inline-flex;align-items:center;gap:8px;margin-bottom:7px;}
.acid-card .ac-k i{width:6px;height:6px;border-radius:50%;background:var(--ink);display:inline-block;}
.acid-card h3,.acid-card .ac-h{font-family:var(--grot);font-weight:800;font-size:clamp(16px,1.9vw,20px);letter-spacing:-.01em;line-height:1.05;margin:0 0 5px;text-transform:none;}
.acid-card .ac-l p{font-family:var(--sans);font-size:12.5px;line-height:1.5;color:#2c2c28;margin:0;max-width:54ch;}
.acid-card .ac-r{display:flex;flex-direction:column;align-items:flex-end;gap:9px;flex:none;}
.acid-card .ac-actions{display:flex;gap:10px;}
.acid-card .qc{height:46px;padding:0 20px;border-color:var(--ink);color:var(--ink);}
.acid-card .qc.accent{background:var(--ink);border-color:var(--ink);color:var(--acid);}
.acid-card .qc.accent.press,.acid-card .qc.accent.tapped,.acid-card .qc.accent:active{background:#fff;border-color:#fff;color:var(--ink);}
.acid-card .ac-note{font-family:var(--mono);font-size:10px;letter-spacing:.05em;color:rgba(19,19,19,.62);text-transform:uppercase;}
@media(max-width:640px){
  .acid-card{flex-direction:column;align-items:stretch;gap:14px;}
  .acid-card .ac-r{align-items:stretch;}
  .acid-card .ac-actions{gap:8px;}
  .acid-card .ac-actions .qc{flex:1;justify-content:center;}
}
/* WO-011 (round 3): below 480 the two card actions stop sharing a row — side-by-side .qc
   buttons drop under their own label width and overflow the card. */
@media(max-width:480px){
  .acid-card .ac-actions{flex-direction:column;}
  .acid-card .ac-actions .qc{width:100%;flex:none;}
}

/* ============================================================================
   WO-012 §0b — chrome cobalt-leak counter (2026-07-26, CC).
   Snippet 109162 `.woocommerce a:not(.button){color:var(--gn-cobalt)}` (0,2,1) beats the header's
   `.ff-nav-link{color:var(--ink)}` (0,1,0). `body.woocommerce` reaches the Theme Builder header/footer,
   so on every /shop/, /product-category/*, /product/*, /cart/, /checkout/ page the nav links, account/
   cart icons, brand and footer links render cobalt. 109162 is protected — counter it here in the
   CC-owned foundation (loads globally on the chrome; :root tokens available; the staging Elementor MCP
   that would edit header widget gnhdw2 is down). Scoped to the chrome wrappers .gn2hdr / .gn2ftr;
   :not(.at-top) preserves the dark-hero white inversion; hovers pinned !important so they survive.
   Reference values MEASURED on a non-Woo page (rest/hover): nav/ico ink→cobalt, footer link
   #C9C7BE→acid, footer-mark #fff, mm links ink, mm arrow cobalt.
   ============================================================================ */
.gn2hdr .ff-head:not(.at-top){background:#F4F2EC!important;}
.gn2hdr .ff-head:not(.at-top) .ff-nav-link,
.gn2hdr .ff-head:not(.at-top) .ff-ico,
.gn2hdr .ff-head:not(.at-top) .ff-brand{color:var(--ink)!important}
.gn2hdr .ff-head:not(.at-top) .ff-nav-link:hover,
.gn2hdr .ff-head:not(.at-top) .ff-nav-link:focus-visible,
.gn2hdr .ff-head:not(.at-top) .ff-ico:hover,
.gn2hdr .ff-head:not(.at-top) .ff-ico:focus-visible{color:var(--cobalt)!important}
.gn2hdr .ff-head.at-top .ff-nav-link,
.gn2hdr .ff-head.at-top .ff-ico,
.gn2hdr .ff-head.at-top .ff-brand{color:#fff!important}
.gn2hdr .ff-head.at-top .ff-ico:hover,
.gn2hdr .ff-head.at-top .ff-ico:focus-visible{color:var(--acid)!important}
.gn2hdr .ff-nav-link .ext{color:#6B6759!important}
.gn2hdr .ff-mm-actions a:not(.ff-flash),.gn2hdr .ff-mm-explore a:not(.ff-flash){color:var(--ink)!important}
.gn2hdr .ff-mm-actions a .ar{color:var(--cobalt)!important}
.gn2ftr .ff-foot a{color:#C9C7BE!important}
.gn2ftr .ff-foot a:hover,.gn2ftr .ff-foot a:focus-visible{color:var(--acid)!important}
.gn2ftr .ff-foot-mark{color:#fff!important}

/* WO-035 — cinematic first-frame header. The header is no longer fixed or scroll-direction driven.
   On a hero route it overlays the first frame and leaves with that frame; elsewhere it remains in
   normal document flow. :has() provides first-paint layout in current browsers; the JS-added body
   class is the safe runtime fallback. */
header.elementor-location-header{height:auto;}
.elementor-location-header .elementor-element-gnhdw1,
.elementor-location-header .elementor-element-gnhdw1>.elementor-widget-container,
.elementor-location-header .gn2hdr{width:100%!important;}
.gn2hdr .ff-head{position:relative!important;top:auto!important;left:auto!important;right:auto!important;transform:none!important;}
:is(body.ff-head-over-hero,body:has(main .ff-hero),body:has(main .wol2-stage),body:has(main .grn-ci-hero),body:has(main .pg-hero),body:has(main .pdm-stage)) header.elementor-location-header{
  height:0;position:relative;z-index:200;
}
:is(body.ff-head-over-hero,body:has(main .ff-hero),body:has(main .wol2-stage),body:has(main .grn-ci-hero),body:has(main .pg-hero),body:has(main .pdm-stage)) .gn2hdr .ff-head{
  position:absolute!important;top:0!important;left:0!important;right:0!important;
  background:transparent!important;border-bottom-color:transparent!important;box-shadow:none!important;
}
:is(body.ff-head-over-hero,body:has(main .ff-hero)) .ff-hero{margin-top:0;}

/* Retail is a white canvas from the global Shop through every coded/archive category and PDP.
   Dark editorial bands and .pg-hero.dark deliberately keep their own surfaces. */
:is(body.woocommerce.archive,body.gn-pdp-route,body.gn-shop-surface){background:#fff!important;}
:is(body.woocommerce.archive,body.gn-pdp-route,body.gn-shop-surface) .gn2hdr .ff-head:not(.at-top){background:#fff!important;}
:is(body.woocommerce.archive,body.gn-shop-surface) :is(.sh--seamless,.sh-shop,.pg-hero:not(.dark)){background:#fff!important;}
body.gn-shop-surface :is(main.fp,.fp-stage,.fp-sec){background:#fff!important;}

@media(max-width:560px){
  .pg-hero-top span:last-child{display:none;}
  .pg-support{overflow-wrap:anywhere;}
}

/* WO-012 Task 7 (design round 2026-07-26) — port from fullframe.css: .qc disabled/gated state,
   .qc-calm cursor-disc opt-out, and the .ff-foot-legal footer row. Verbatim; --line/--mut/--line-dark
   resolve identically in the foundation and the design source. Three-tier contract: signature .qc = disc
   + Light-Cast; .qc-calm = Light-Cast only (no disc); .qc-lite = underline sweep (no disc). */
.qc:disabled,.qc[aria-disabled="true"],.qc.qc-off{background:transparent!important;border-color:var(--line)!important;color:var(--mut)!important;cursor:not-allowed;box-shadow:none!important;transform:none!important;}
.qc:disabled .arw,.qc[aria-disabled="true"] .arw,.qc.qc-off .arw{color:var(--mut)!important;}
.qc:disabled .qc-lens,.qc[aria-disabled="true"] .qc-lens,.qc.qc-off .qc-lens,
.qc:disabled .print,.qc[aria-disabled="true"] .print,.qc.qc-off .print,
.qc:disabled .lume,.qc[aria-disabled="true"] .lume,.qc.qc-off .lume{display:none!important;}
.on-dark .qc:disabled,.cta-band:not(.acid):not(.cobalt) .qc:disabled,.fdb-sum-cta .qc:disabled,.fdb-bar-cta .qc:disabled,
.on-dark .qc.qc-off,.fdb-sum-cta .qc.qc-off,.fdb-bar-cta .qc.qc-off{border-color:rgba(255,255,255,.22)!important;color:rgba(255,255,255,.38)!important;}
.on-dark .qc:disabled .arw,.fdb-sum-cta .qc:disabled .arw,.fdb-bar-cta .qc:disabled .arw{color:rgba(255,255,255,.38)!important;}
.qc.qc-calm .qc-lens{display:none!important;}
.ff-foot-legal{display:flex;flex-wrap:wrap;gap:6px 22px;padding:14px 0 2px;border-top:1px solid var(--line-dark);font-family:var(--mono);font-size:10.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;}
.ff-foot-legal a{color:#9d9b93;}
.ff-foot-legal a:hover{color:var(--acid);}

/* WO-038 contrast sweep. --mut is tuned for light paper; the same token failed
   WCAG AA when inherited by small mono text on the void surface. Scope a lighter
   muted token to dark editorial/footer surfaces, keep the mobile menu's light
   footer on the darker light-surface token, and counter the footer template's
   legacy #67736C base line. */
.ff-sec.dark,.pg-sec.dark,.pg-hero.dark,.ff-foot{--mut:#8C8A80;}
.ff-sec.dark .ff-mast,.pg-sec.dark .ff-mast,.pg-hero.dark .ff-mast{color:var(--mut);}
.gn2ftr .ff-foot-base{color:#8C8A80!important;}
.gn2hdr .ff-mm-foot{color:#6B6759!important;}
.nrd-hero .nh-scroll{color:#8C8A80!important;}
main .field .req{color:var(--red,#C0392B)!important;}
.wol2 .wol2-hero h1{color:#fff!important;}


/* ============================================================
   KEYBOARD FOCUS CONTRACT (B2, approved 2026-07-26)
   One visible focus treatment for every interactive element,
   matching the builder's existing cobalt outline. Surface-aware:
   cobalt on light, acid on dark, ink on acid, white on cobalt.
   :focus-visible only — mouse/touch focus stays clean.
   ============================================================ */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,summary:focus-visible,[tabindex]:not([tabindex="-1"]):focus-visible{outline:2px solid var(--cobalt);outline-offset:3px;}
.ff-sec.dark :focus-visible,.cta-band :focus-visible,.ff-foot :focus-visible,.pg-hero.dark :focus-visible,.ff-mm :focus-visible{outline-color:var(--acid);}
.cta-band.acid :focus-visible,.acid-card :focus-visible{outline-color:var(--ink);}
.cta-band.cobalt :focus-visible{outline-color:#fff;}

/* ============================================================
   WO-013 Task 3 — one ground per page (structural, value unchanged)
   Kit 2537 paints .elementor-kit-2537{background-color:#F4F2EC} on <body>
   (0,1,0), out-specifying our body{background:var(--bone)} (0,0,1), so every
   surface that doesn't paint its own ground leaked the kit value while painted
   surfaces showed bone → two grounds met mid-page. Raise our body rule ABOVE the
   kit (0,1,1), still deriving from --bone, so exactly one ground computes now and
   the approved value change to --bone (Claude Design) propagates automatically.
   Do NOT touch kit 2537. ============================================================ */
/* r26f PERMANENT --gn-* SHIM + per-token DECISION TABLE (2026-07-27) -----------
   PERMANENT infrastructure - NOT transitional, NOT a bridge, does NOT retire. It is the durable source of
   the --gn-* palette: aliases every shop token to its foundation equivalent and OVERRIDES snippet 109162's
   stale :root on all 36 pages. 109162's SOURCE re-cut is ABANDONED - it is hook-protected and can only be
   re-cut through the production connector (no safe path on staging; a raw edit desyncs its integrity hash
   and it stops rendering its .shop_table rules). The shim overrides 109162's stale tokens - verified - so
   the re-cut is functionally moot. The per-token DECISION TABLE below (DUPLICATE alias / DISTINCT literal /
   STRAY) is THE durable artifact: do NOT reclassify a token from "looks the same" - that error happened
   twice. --gn-paper is #fff/var(--white), a DISTINCT tier from --paper #FBFAF6 (round-e ruling, NEVER fold
   to --paper); bone/line/mut carry the round-e/c-fold values; --gn-cobalt-d aliases --cobalt-700 (round-g
   fold, stray #0a4fd8 retired). No fallbacks by design. Do NOT touch kit 2537. */
body.elementor-kit-2537{background-color:var(--bone);
/* --gn-* DECISION TABLE (audited 2026-07-27). Each token is a DUPLICATE of a foundation token (fold:
   alias) or a DISTINCT TIER with no twin (keep literal). Only a Claude Design ruling flips a class -
   do NOT reclassify from "looks the same". This is why the shim was wrong twice (bone hardcoded, paper aliased). */
/* DUPLICATES - alias to foundation (identical value): */
--gn-bone:var(--bone);/* DUPLICATE #F4F2EC - folded round e */
--fp-bone:var(--bone);/* DUPLICATE - Frames bone == foundation bone */
--gn-line:var(--line);/* DUPLICATE #DAD7CC - folded round c */
--gn-mut:var(--mut);/* DUPLICATE #6B6759 - folded round c (AA-passing) */
--gn-ink:var(--ink);/* DUPLICATE #131313 - folded r26f; shop had surface-black #0B0B0B, wrong for type */
--gn-cobalt:var(--cobalt);--gn-cobalt-700:var(--cobalt-700);/* DUPLICATE #0048CC - added round-f; 109162 direct re-cut broke EMCP loading, shim covers it *//* DUPLICATE #005BFF */
--gn-void:var(--void);/* DUPLICATE #0B0B0B - audited 2026-07-27 */
--gn-acid:var(--acid);/* DUPLICATE #B6FF00 - audited */
--gn-amber:var(--amber);/* DUPLICATE #FFB000 - audited */
--gn-sans:var(--sans);/* DUPLICATE - NHG Text stack */
--gn-grot:var(--grot);/* DUPLICATE - NHG Display stack; killed phantom 'Pro' r26f */
--gn-mono:var(--mono);/* DUPLICATE - IBM Plex Mono */
/* DISTINCT TIERS - no foundation twin; keep the literal, NEVER alias: */
/* RECLASSIFIED round-f 2026-07-27: these were DISTINCT (no twin) until fullframe.css absorbed the
   shop-invented semantics. Now DUPLICATE - not the table being wrong, the table WORKING. Values byte-identical: */
--gn-paper:var(--white);/* DUPLICATE #FFFFFF - was DISTINCT #fff; round-f added --white twin (#fff==#FFFFFF same white). --paper #FBFAF6 is STILL a different tier. */
--gn-soft:var(--soft);/* DUPLICATE #EDEBE3 - was DISTINCT; round-f foundation absorbed --soft */
--gn-red:var(--red);/* DUPLICATE #C0392B - was DISTINCT; round-f absorbed --red */
--gn-ok:var(--ok);/* DUPLICATE #1F9D55 - was DISTINCT; round-f absorbed --ok */
--gn-warn:var(--warn);/* DUPLICATE #C77D0A - was DISTINCT; round-f absorbed --warn */
/* STRAY retired: */
--gn-cobalt-d:var(--cobalt-700);/* STRAY - #0a4fd8 off the cobalt hue line; retired round g, --cobalt-700 #0048CC canonical */
}

/* r-cutover: Woo checkout payment box must not overflow narrow viewports (Square gateway fieldset + ul.payment_methods indent) */
.woocommerce-checkout ul.payment_methods{padding-left:0;margin-left:0;list-style:none;}
.woocommerce-checkout .wc_payment_method,.woocommerce-checkout .payment_box,.woocommerce-checkout .payment_box fieldset,.woocommerce-checkout .payment_box input{max-width:100%;box-sizing:border-box;}

/* arrow ↗ (U+2197) must render as a text glyph, never the iOS emoji */
body.elementor-kit-2537,main.g2main{font-variant-emoji:text;}

/* Price-card thumb must contain its absolutely-positioned .ff-plate image placeholder.
   Without image-slot.js on 2.0 coded pages, .pc-thumb had no positioned ancestor, so .ff-plate
   (position:absolute;inset:0;background:#15140f) escaped to the section and painted a giant black
   plate over the Archive & Digitize pricing bento. Parity fix 2026-07-31. */
.pc-thumb{position:relative;}

/* WO-036 2B (item 6) — WCAG 2.2 Target Size (2.5.8). The header brand link is a standalone flex
   control rendering only 18px tall (the logo height), so it fails 2.5.8 at widths where the
   breadcrumb sits ~22px away (spacing exception < 24px). Give it a >=24px CSS-px hit area, flex-
   centred so the logo's visual size is unchanged. Shared chrome; scoped to the brand link only. */
.gn2hdr .ff-brand { min-height: 24px; align-items: center; }
