/* National Lumber motion, taken from the drawing set: plotter lines, dimension strings, crop marks,
   stacked sheets, stamps. Hidden states need html.mo-live (motion.js) plus an element it marked. */
:root{--mo-ease:cubic-bezier(.2,.7,.1,1);--mo-gold:#BA8B37;--mo-ink:#102441;--mo-mono:'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,monospace;
 --mo-tick:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9'%3E%3Cpath d='M.5 8.5l8-8' stroke='%23BA8B37' stroke-width='1.3'/%3E%3C/svg%3E")}

/* 7. Only clickable things answer the pointer (colour, border, underline), 120-180 ms. */
:where(.btn,.access-submit,.tk-watch>span,.nl-account-link,.nav-toggle,.ai-tier,.sr-tabs button,.vp-guide-tabs button,.tk-chapters button){transition:background-color .16s,border-color .16s,color .16s,transform .12s}
:where(.btn,.access-submit,.ai-tier,.sr-tabs button):active{transform:translateY(1px)}
:where(.site-nav>a,.desk-head a,#desk-nav a){transition:background-color .15s,color .15s}
:where(.tk-text-link,.vp-quiet-link,.ni-text-link,.site-foot a,.vp-photo figcaption a,.access-footer a,.desk-footer a,.auth-alt a,.est-consent a){transition:text-decoration-color .16s,text-decoration-thickness .16s,color .16s}
@media(hover:hover){:where(.tk-text-link,.vp-quiet-link,.ni-text-link,.site-foot a,.vp-photo figcaption a,.access-footer a,.desk-footer a,.auth-alt a,.est-consent a):hover{text-decoration-color:var(--mo-gold);text-decoration-thickness:2px}
 .tk-watch:hover>span{border-color:var(--mo-gold)}}
:where(a,button,summary,input,select,textarea,[tabindex]):focus-visible{outline:3px solid #94702e;outline-offset:3px}
/* Headings and panels that receive focus from a script (tabindex=-1, never in the tab order) move the
   reading position for assistive tech; they are not controls, so they draw no ring. */
:is(h1,h2,h3,h4,h5,p,span,div,section,article,aside,ol,ul,dialog)[tabindex="-1"]:focus{outline:none}

/* 3. Crop marks register on interactive cards on hover or focus. */
:is(.desk-record,.sr-review :is(.sr-material,.sr-discrepancy,.sr-sheet>summary),.tk-chapters button,.access-panel,.ni-auth .auth-card){position:relative}
:is(.desk-record,.sr-review :is(.sr-material,.sr-discrepancy,.sr-sheet>summary),.tk-chapters button,.access-panel,.ni-auth .auth-card)::before{content:"";position:absolute;inset:5px;z-index:1;pointer-events:none;opacity:0;transform:scale(1.035);transition:opacity .14s ease,transform .18s var(--mo-ease);
 --c:linear-gradient(var(--mo-gold),var(--mo-gold));background:var(--c) 0 0/11px 1px,var(--c) 0 0/1px 11px,var(--c) 100% 0/11px 1px,var(--c) 100% 0/1px 11px,var(--c) 0 100%/11px 1px,var(--c) 0 100%/1px 11px,var(--c) 100% 100%/11px 1px,var(--c) 100% 100%/1px 11px;background-repeat:no-repeat}
.private-login .access-panel.access-panel::before{inset:-14px -16px}
@media(hover:hover){:is(.desk-record,.sr-review :is(.sr-material,.sr-discrepancy,.sr-sheet>summary),.tk-chapters button):hover::before{opacity:1;transform:none}}
:is(.desk-record,.sr-review :is(.sr-material,.sr-discrepancy),.tk-chapters button,.access-panel,.ni-auth .auth-card):focus-within::before,.sr-review .sr-sheet>summary:focus-visible::before{opacity:1;transform:none}

/* Dropzone: its crop marks snap in on hover/focus and register to the corners on drag. A tap is not a
   hover (the marks would stay lit after the file picker closes); the bottom marks span the whole sheet. */
#ai #ai-dropzone{--mo-o:0;--mo-c:5px;--mo-k:var(--mo-ink)}
@media(hover:hover){#ai #ai-dropzone:hover{--mo-o:1;--mo-c:0px}}
#ai #ai-dropzone:is(:focus-visible,.drag){--mo-o:1;--mo-c:0px}#ai #ai-dropzone.drag{--mo-c:-6px;--mo-k:var(--mo-gold)}
#ai #ai-dropzone .dz-cm{display:block;max-width:none}
#ai #ai-dropzone::before,#ai #ai-dropzone::after,#ai #ai-dropzone .dz-cm::before,#ai #ai-dropzone .dz-cm::after{display:block;border-color:var(--mo-k);opacity:var(--mo-o);transform:translate(calc(var(--sx,1)*var(--mo-c)),calc(var(--sy,1)*var(--mo-c)));transition:opacity .14s,transform .2s var(--mo-ease),border-color .16s}
#ai #ai-dropzone::after{--sx:-1}#ai #ai-dropzone .dz-cm::before{--sy:-1}#ai #ai-dropzone .dz-cm::after{--sx:-1;--sy:-1}
.mo-live #ai-dropzone.drag .dz-icon{animation:mo-pulse .5s var(--mo-ease)}
@keyframes mo-pulse{40%{transform:scale(1.12)}}

/* 2. Home hero: a floor framing plan plotted line by line over the navy. */
.tk-hero .tk-hero-content{position:relative;z-index:1}.tk-hero .tk-motion-toggle{z-index:2}
.tk-hero .mo-plan{position:absolute;z-index:0;pointer-events:none;right:3.5%;top:50%;width:min(43vw,620px);height:auto;transform:translateY(-50%);overflow:visible;
 /* the plan is plotted on its own sheet of vellum, so it never fights the footage behind it */
 background:rgba(16,36,65,.58);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);box-shadow:0 0 0 1px rgba(246,244,238,.16),0 30px 80px rgba(6,14,28,.35)}
.mo-live .tk-hero .mo-plan{animation:mo-vellum .7s var(--mo-ease) .15s backwards}
@keyframes mo-vellum{from{opacity:0;transform:translateY(calc(-50% + 14px))}}
@media(max-width:1100px){.tk-hero .mo-plan{right:2%;width:min(40vw,440px);opacity:.7}}
@media(max-width:900px){.tk-hero .mo-plan{display:none}}
.mo-plan path,.mo-plan circle{fill:none;stroke:#F6F4EE;stroke-linecap:square}
.mo-plan .g{stroke-opacity:.22;stroke-width:.8;stroke-dasharray:16 4 2 4}.mo-plan .w{stroke-opacity:.72;stroke-width:1.5}.mo-plan .j{stroke-opacity:.38;stroke-width:1}
.mo-plan .t{stroke-opacity:.8;stroke-width:1.2}.mo-plan .r{stroke-opacity:.45;stroke-width:.8}.mo-plan .b{stroke-opacity:.6;stroke-width:1.6;stroke-dasharray:9 5}
.mo-plan .dm{stroke:#D9B36A;stroke-opacity:.9;stroke-width:.9}.mo-plan text{font:500 9.5px var(--mo-mono);letter-spacing:.06em;fill:#F6F4EE;fill-opacity:.7}.mo-plan .gt{fill:#D9B36A;fill-opacity:.95}
.mo-plan .s{stroke-dasharray:1 1;stroke-dashoffset:0}
.mo-live .mo-plan .s{stroke-dashoffset:1;animation:mo-draw var(--t,520ms) var(--mo-ease) calc(var(--d,0)*1ms) forwards}
.mo-live .mo-plan .f{opacity:0;animation:mo-fade 600ms ease calc(var(--d,0)*1ms) forwards}
.mo-live .mo-plan:not(.mo-run) :is(.s,.f),.mo-live .mo-plan.mo-hold :is(.s,.f){animation-play-state:paused}
@keyframes mo-draw{to{stroke-dashoffset:0}}@keyframes mo-fade{from{opacity:0}to{opacity:1}}

/* 1. Headings: plotter wipe, then a dimension string with its sheet number. */
[data-mo-dim]{position:relative}
[data-mo-dim]::after{content:"";position:absolute;left:var(--mo-x,0);bottom:var(--mo-b,-14px);width:min(var(--mo-w,6ch),100%);height:9px;pointer-events:none;background:var(--mo-tick) 0 50%/9px 9px no-repeat,var(--mo-tick) 100% 50%/9px 9px no-repeat,linear-gradient(var(--mo-gold),var(--mo-gold)) 0 50%/100% 1px no-repeat}
[data-mo-dim]:not([data-mo-dim=""])::before{content:"";content:attr(data-mo-dim) / "";position:absolute;left:min(calc(var(--mo-x,0px) + var(--mo-w,6ch) + 8px),calc(100% - 26px));bottom:calc(var(--mo-b,-14px) - 2px);font:500 10px/13px var(--mo-mono);letter-spacing:.14em;color:#94702e;pointer-events:none;white-space:nowrap}
.mo-live [data-mo-dim]:not(.mo-in)::after{clip-path:inset(0 100% 0 0)}.mo-live [data-mo-dim]:not(.mo-in)::before{opacity:0}
.mo-live [data-mo-dim].mo-in::after{animation:mo-line .8s var(--mo-ease) var(--mo-delay,.18s) backwards}
.mo-live [data-mo-dim].mo-in::before{animation:mo-fade .4s ease calc(var(--mo-delay,.18s) + .55s) backwards}
.mo-live [data-mo-wipe]:not(.mo-in){clip-path:inset(-.3em 100% -48px -.3em)}
.mo-live [data-mo-wipe].mo-in{animation:mo-wipe .75s var(--mo-ease) backwards}
@keyframes mo-line{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0)}}
@keyframes mo-wipe{from{clip-path:inset(-.3em 100% -48px -.3em)}to{clip-path:inset(-.3em -.3em -48px -.3em)}}

/* Photos feed out like a plotted sheet; rows move along the carriage axis. */
.mo-live [data-mo-feed]:not(.mo-in){clip-path:inset(0 0 100% 0)}
.mo-live [data-mo-feed].mo-in{animation:mo-feed .9s var(--mo-ease) backwards}
@keyframes mo-feed{from{clip-path:inset(0 0 100% 0)}to{clip-path:inset(0)}}
.mo-live [data-mo-rise]:not(.mo-in){opacity:0}
.mo-live [data-mo-rise].mo-in{animation:mo-rise .46s var(--mo-ease) calc(var(--mo-i,0)*42ms) backwards}
.mo-live tr[data-mo-rise].mo-in{animation-name:mo-fade}
@keyframes mo-rise{from{opacity:0;transform:translateX(-10px)}}

/* 4. Upload and reading: sheets land on the stack; while the read runs, a plotter carriage passes over
   the drawing-set register (never over text) and its sheets fill in as pages are indexed and read. */
.mo-live #ai-file-list>li.mo-sheet{animation:mo-sheet .42s var(--mo-ease) calc(var(--mo-i,0)*55ms) backwards}
@keyframes mo-sheet{from{opacity:0;transform:translate(-14px,-12px) rotate(-1.6deg)}}
.tw-reading .ai-elapsed{font-family:var(--mo-mono);font-variant-numeric:tabular-nums;letter-spacing:.02em}
.mo-live .tw-register-grid::after{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(90deg,transparent calc(100% - 72px),rgba(186,139,55,.16) calc(100% - 2px),var(--mo-gold) calc(100% - 2px));transform:translateX(-100%);animation:mo-scan 3.8s cubic-bezier(.45,0,.55,1) infinite alternate}
@keyframes mo-scan{to{transform:translateX(0)}}
.mo-live .tw-register-grid i{transition:background-color .35s ease calc(var(--i,0)*16ms),border-color .35s ease calc(var(--i,0)*16ms)}
.mo-live .tw-register-grid i.is-next{animation:mo-next 1.1s ease-in-out infinite alternate}
@keyframes mo-next{to{background-color:#f1e3c6}}
.mo-live .tw-register-groups i{transition:background-color .4s ease}
/* The result feeds in where the reading panel was: opacity and transform only, nothing below moves. */
.mo-live #ai-out.tw-arrive>*{animation:mo-arrive .6s var(--mo-ease) calc(var(--tw-k,6)*80ms) backwards}
@keyframes mo-arrive{from{opacity:0;transform:translateY(12px)}}
.mo-live .takeoff-workspace[data-takeoff-state=opening] #ai-out::after{content:"";position:absolute;inset:26px 22px;pointer-events:none;background:linear-gradient(90deg,transparent calc(100% - 90px),rgba(186,139,55,.12) calc(100% - 2px),var(--mo-gold) calc(100% - 2px));transform:translateX(-100%);animation:mo-scan 1.6s cubic-bezier(.45,0,.55,1) infinite alternate}

/* 5. Results: numbers in Plex Mono count up once; finished states are stamped. */
:is(.sr-metrics dd,.ai-price-row .pq,.sr-quantity,.tw-result-body td.qty:not(.conf)){font-family:var(--mo-mono);font-variant-numeric:tabular-nums;letter-spacing:0}
.mo-counting{position:relative;-webkit-text-fill-color:transparent}
.mo-counting::before{-webkit-text-fill-color:currentcolor}
.mo-counting::after{content:"";content:var(--mo-n) / "";position:absolute;inset:0;display:flex;align-items:var(--mo-a,flex-start);justify-content:var(--mo-j,flex-start);padding:inherit;font:inherit;letter-spacing:inherit;white-space:nowrap;-webkit-text-fill-color:currentcolor;pointer-events:none}
.mo-live .tw-received-mark{animation:mo-stamp .55s var(--mo-ease) .12s backwards}
.mo-live .tw-read-steps li.is-complete::before{animation:mo-stamp .45s var(--mo-ease) backwards}
.mo-live .tw-result-overview .tw-preliminary{transform-origin:0 50%;animation:mo-stamp-s .5s var(--mo-ease) .15s backwards}
@keyframes mo-stamp{0%{opacity:0;transform:scale(1.5) rotate(-9deg)}55%{opacity:1;transform:scale(.95) rotate(-2deg)}}
@keyframes mo-stamp-s{0%{opacity:0;transform:scale(1.12)}60%{opacity:1;transform:scale(.98)}}

/* Progress strip: the bottom rule is drawn up to the current step. */
.takeoff-workspace .tk-progress{position:relative}
.takeoff-workspace .tk-progress::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--mo-gold);transform-origin:0 50%;transform:scaleX(var(--mo-p,0));pointer-events:none}
.mo-live .takeoff-workspace .tk-progress::after{transition:transform .9s var(--mo-ease) .2s}
@media(max-width:700px){.takeoff-workspace .tk-progress::after{display:none}}

/* Smooth expand/collapse where ::details-content exists. */
@supports selector(::details-content){
 .mo-live main details:not(#ai-input-panel){interpolate-size:allow-keywords}
 .mo-live main details:not(#ai-input-panel)::details-content{height:0;opacity:0;overflow:clip;overflow-clip-margin:8px;transition:height .34s var(--mo-ease),opacity .26s ease,content-visibility .34s allow-discrete}
 .mo-live main details[open]:not(#ai-input-panel)::details-content{height:auto;opacity:1}
}

/* 6. Page transitions: header stays, main wipes in (names set by motion.js during navigation). */
@media(prefers-reduced-motion:no-preference){@view-transition{navigation:auto}}
::view-transition-group(nl-head){animation:none}::view-transition-old(nl-head){display:none}::view-transition-new(nl-head){animation:none}
::view-transition-group(nl-main){animation-duration:.56s}
::view-transition-old(nl-main){animation:mo-out .13s ease both}
::view-transition-new(nl-main){animation:mo-wipe-in .5s var(--mo-ease) .06s both}
::view-transition-old(root){animation:mo-out .2s ease both}::view-transition-new(root){animation:mo-fade .26s ease both}
@keyframes mo-out{to{opacity:0}}@keyframes mo-wipe-in{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0)}}

/* 8. Reduced motion: final states, no movement. Print: everything on paper. */
@media(prefers-reduced-motion:reduce){:where(.btn,.access-submit,.ai-tier,.sr-tabs button):active{transform:none}
 :is(.desk-record,.sr-review :is(.sr-material,.sr-discrepancy,.sr-sheet>summary),.tk-chapters button,.access-panel,.ni-auth .auth-card)::before{transform:none;transition:none}
 #ai #ai-dropzone::before,#ai #ai-dropzone::after,#ai #ai-dropzone .dz-cm::before,#ai #ai-dropzone .dz-cm::after{transition:none}}
@media print{.mo-plan,[data-mo-dim]::after,[data-mo-dim]::before,.tw-register-grid::after{display:none!important}[data-mo-wipe],[data-mo-feed],[data-mo-rise]{clip-path:none!important;opacity:1!important;animation:none!important}}
