/* Treasure box tool. Shares the BNEBuilds design system with the planter
   (site/planner.css): same palette, fonts, and control furniture, so the two
   tools read as one family. Kept as its own file because this tool deploys to
   its own /boxes root, independent of the planter's site/ folder. */

/* Self-hosted fonts (BUILDS-16): Saira Condensed, IBM Plex Sans, IBM Plex Mono,
   vendored under ./fonts/ so the page has no runtime dependency on Google Fonts.
   Same files as the planter's (site/fonts/), copied rather than re-fetched so
   the two folders cannot drift apart. Subsetted to latin + latin-ext; the
   unicode-range values below are copied verbatim from fonts.googleapis.com's own
   stylesheet, so a browser still only fetches whichever subset a page actually
   needs.
   IBM Plex Sans ships upstream as a variable font: Google serves the SAME file
   for weights 400/500/600, so the three rules below (per subset) point at the
   same two local files and let font-weight select within them, matching
   upstream exactly. Saira Condensed and IBM Plex Mono are static per weight, so
   each weight has its own pair of files.
   SIL Open Font License 1.1 for both families; text travels with the files at
   fonts/OFL-IBM-Plex.txt and fonts/OFL-Saira-Condensed.txt. */
@font-face{font-family:'Saira Condensed';font-style:normal;font-weight:500;font-display:swap;src:url(./fonts/saira-condensed-500-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'Saira Condensed';font-style:normal;font-weight:500;font-display:swap;src:url(./fonts/saira-condensed-500-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Saira Condensed';font-style:normal;font-weight:700;font-display:swap;src:url(./fonts/saira-condensed-700-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'Saira Condensed';font-style:normal;font-weight:700;font-display:swap;src:url(./fonts/saira-condensed-700-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Saira Condensed';font-style:normal;font-weight:800;font-display:swap;src:url(./fonts/saira-condensed-800-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'Saira Condensed';font-style:normal;font-weight:800;font-display:swap;src:url(./fonts/saira-condensed-800-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:400;font-stretch:100%;font-display:swap;src:url(./fonts/ibm-plex-sans-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:400;font-stretch:100%;font-display:swap;src:url(./fonts/ibm-plex-sans-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url(./fonts/ibm-plex-sans-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url(./fonts/ibm-plex-sans-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:600;font-stretch:100%;font-display:swap;src:url(./fonts/ibm-plex-sans-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:600;font-stretch:100%;font-display:swap;src:url(./fonts/ibm-plex-sans-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url(./fonts/ibm-plex-mono-400-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url(./fonts/ibm-plex-mono-400-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url(./fonts/ibm-plex-mono-500-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url(./fonts/ibm-plex-mono-500-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;src:url(./fonts/ibm-plex-mono-600-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;src:url(./fonts/ibm-plex-mono-600-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}

:root{
  --treated:#dfe6dc;
  --treated-deep:#cdd8c9;
  --board:#f2ecdd;
  --board-edge:#c8b895;
  --ink:#16221c;
  --ink-soft:#4b5b52;
  --ink-faint:#526056;
  --copper:#1d6b58;
  --copper-lift:#25876f;
  --stamp:#a8322a;
  --amber:#8a6d1f;
  --rule:#b6c2b3;
  --paper:#fff;
}
*{box-sizing:border-box}
html,body{margin:0}
body{
  background:var(--treated);
  color:var(--ink);
  font-family:"IBM Plex Sans",system-ui,sans-serif;
  font-size:17.2px;
  line-height:1.5;
}
.wrap{max-width:min(1800px,96vw);margin:0 auto;padding:0 20px}
.lede,.foot p{max-width:70ch}

/* ---------- masthead ---------- */
.masthead{border-bottom:2px solid var(--ink);background:var(--treated)}
.mast-inner{padding:30px 20px 20px}
h1{
  font-family:"Saira Condensed",sans-serif;font-weight:800;
  font-size:clamp(38px,7vw,64px);text-transform:uppercase;
  letter-spacing:-.015em;line-height:.92;margin:0;
}
h1 span{color:var(--copper)}
.lede{max-width:60ch;margin:10px 0 0;color:var(--ink-soft)}

/* ---------- layout ---------- */
.layout{display:grid;grid-template-columns:334px 1fr;gap:22px;padding:22px 20px 10px;align-items:start}
.layout>.output{min-width:0}
.panel{background:var(--paper);border:1px solid var(--rule);border-radius:3px;padding:18px}
.controls{position:sticky;top:16px;max-height:calc(100vh - 32px);overflow-y:auto}

h2{
  font-family:"Saira Condensed",sans-serif;font-weight:700;font-size:19.5px;
  text-transform:uppercase;letter-spacing:.08em;margin:0 0 12px;
  padding-bottom:6px;border-bottom:1px solid var(--rule);
}
.controls h2:not(:first-child){margin-top:26px}

.ctl{margin-bottom:16px}
.ctl label,.ctl legend{
  display:block;font-family:"Saira Condensed",sans-serif;font-weight:700;
  font-size:13.2px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-soft);margin-bottom:6px;
}
.ctl label .val{
  float:right;font-family:"IBM Plex Mono",monospace;font-size:13.2px;
  letter-spacing:0;text-transform:none;color:var(--copper);font-weight:600;
}
/* The readout is an editable type-in field (BUILDS-100). It reads as plain text
   until hovered or focused, when a dotted underline signals it takes typing. */
.ctl label input.val{
  width:6em;text-align:right;padding:1px 3px;margin:-1px 0;
  border:0;border-bottom:1px dotted transparent;background:transparent;
  border-radius:3px;cursor:text;-moz-appearance:textfield;
}
.ctl label input.val:hover{border-bottom-color:var(--rule)}
.ctl label input.val:focus{
  outline:none;background:var(--paper);border-bottom-color:var(--copper);
}
.seg{display:flex;flex-wrap:wrap;gap:5px}
.seg button{
  flex:1 1 auto;min-width:44px;font-family:"IBM Plex Mono",monospace;
  font-size:14.9px;padding:7px 4px;border:1px solid var(--rule);
  background:var(--paper);color:var(--ink-soft);border-radius:2px;cursor:pointer;
}
.seg button:hover{border-color:var(--copper);color:var(--ink)}
.seg button[aria-pressed=true]{background:var(--copper);border-color:var(--copper);color:#fff;font-weight:600}

select{
  width:100%;font-family:"IBM Plex Sans",sans-serif;font-size:16.1px;
  color:var(--ink);background:var(--paper);border:1px solid var(--rule);
  border-radius:2px;padding:8px 9px;
}
:focus-visible{outline:2px solid var(--copper);outline-offset:2px}

/* Range sliders for the continuous dimensions. */
input[type=range]{
  -webkit-appearance:none;appearance:none;width:100%;height:4px;
  background:var(--treated-deep);border-radius:2px;outline-offset:4px;margin:8px 0 2px;
}
input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;
  background:var(--copper);border:2px solid var(--paper);cursor:pointer;box-shadow:0 0 0 1px var(--rule);
}
input[type=range]::-moz-range-thumb{
  width:18px;height:18px;border-radius:50%;background:var(--copper);
  border:2px solid var(--paper);cursor:pointer;box-shadow:0 0 0 1px var(--rule);
}

.hint{margin:6px 0 0;font-size:13.2px;color:var(--ink-faint);line-height:1.45}

/* ---------- readout ---------- */
.readout{border-bottom:1px solid var(--rule);padding-bottom:10px}
/* Output header: box dimensions on the left, the Buy PDF call to action on the
   right. The rule underneath spans the whole header, not just the readout.
   BUILDS-48. */
.output-head{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;
  border-bottom:1px solid var(--rule);padding-bottom:10px}
.output-head .readout{border-bottom:0;padding-bottom:0}
.buy{flex:none;text-align:right}
.buy-pdf{background:#8a6d1f;border-color:#8a6d1f;padding:11px 20px}
.buy-pdf:hover{background:#a5842a;border-color:#a5842a}
.buy-note{margin:7px 0 0;font-size:13.2px;color:var(--ink-soft);max-width:24ch}

/* Cold-start notice: a dismissable centered modal shown while checkout is being
   set up, since the first request can take a moment. Temporary, for the
   soft-launch window (see showColdModal in boxes.js). */
.cold-modal{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:20px}
.cold-backdrop{position:absolute;inset:0;background:rgba(22,34,28,.55)}
.cold-card{
  position:relative;max-width:400px;width:100%;background:var(--paper);
  border:1px solid var(--rule);border-radius:4px;padding:24px 26px;
  box-shadow:0 20px 50px -12px rgba(22,34,28,.45);
}
.cold-card h3{
  font-family:"Saira Condensed",sans-serif;font-weight:800;font-size:22px;
  text-transform:uppercase;letter-spacing:.02em;margin:0 0 8px;color:var(--ink);
}
.cold-card p{margin:0;line-height:1.5;color:var(--ink-soft)}
.cold-x{
  position:absolute;top:6px;right:10px;background:none;border:none;
  font-size:26px;line-height:1;color:var(--ink-soft);cursor:pointer;padding:2px 6px;
}
.cold-x:hover{color:var(--ink)}

/* ---------- Buy PDF button animations ----------
   A quiet SVG flourish that mounts behind the button, plays once, and is removed
   (see BUY_ANIM in boxes.js). The mount never takes pointer events, so the button
   stays a normal control, and it is absolutely positioned so it never shifts
   layout. The scissors is the box tool's; more will join it. */
.buy-anim-wrap{position:relative;display:inline-block}
.buy-anim-wrap > .btn{position:relative;z-index:1}
.buy-anim-mount{
  position:absolute;left:50%;top:50%;width:300px;height:200px;
  transform:translate(-50%,-50%);pointer-events:none;z-index:0;
}
.buy-anim-mount svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
@media (prefers-reduced-motion:reduce){ .buy-anim-mount{display:none!important} }

@keyframes coupon-cut{ 0%{stroke-dashoffset:584;} 62%{stroke-dashoffset:0;} 100%{stroke-dashoffset:0;} }
@keyframes snip-upper{ 0%,100%{ transform:rotate(-9deg); } 50%{ transform:rotate(1deg); } }
@keyframes snip-lower{ 0%,100%{ transform:rotate(9deg); } 50%{ transform:rotate(-1deg); } }
@keyframes snip-ride{
  0%   { offset-distance:0%; opacity:0; }
  4%   { opacity:1; }
  62%  { offset-distance:100%; opacity:1; }
  72%,100% { offset-distance:100%; opacity:0; }
}
@keyframes chad{
  0%, 10% { transform:translate(0,0) rotate(0deg); opacity:0; }
  14%     { opacity:.85; }
  100%    { transform:translate(-6px, 26px) rotate(70deg); opacity:0; }
}
.readout h2{
  font-family:"Saira Condensed",sans-serif;font-weight:800;font-size:34.5px;
  letter-spacing:.01em;margin:0;line-height:1.05;text-transform:none;
  color:var(--ink);border:none;padding:0;
}
.readout p{margin:3px 0 0;font-family:"IBM Plex Mono",monospace;font-size:14.4px;color:var(--ink-faint)}

/* ---------- tabs ---------- */
.tabs{display:flex;flex-wrap:wrap;gap:4px;margin:22px 0 0;border-bottom:1px solid var(--rule);padding-bottom:0}
.tabs button{
  font-family:"Saira Condensed",sans-serif;font-weight:700;font-size:14.4px;
  letter-spacing:.06em;text-transform:uppercase;padding:8px 12px;
  border:1px solid transparent;border-bottom:none;background:none;
  color:var(--ink-soft);cursor:pointer;border-radius:2px 2px 0 0;
}
.tabs button:hover{color:var(--ink);background:var(--treated)}
.tabs button[aria-selected=true]{background:var(--treated-deep);border-color:var(--rule);color:var(--ink);margin-bottom:-1px}

/* ---------- zoom ---------- */
.zoombar{display:flex;align-items:center;gap:10px;margin-top:12px}
.zoombar>span{
  font-family:"Saira Condensed",sans-serif;font-weight:700;font-size:12.1px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint);
}
.seg.small button{font-size:12.6px;padding:3px 8px}

/* ---------- sheet ---------- */
/* The 3D Assembled view (model-viewer). */
model-viewer.viewer3d{
  display:block;width:100%;height:min(70vh,600px);
  background:var(--paper);border:1px solid var(--rule);border-radius:5px;
  --poster-color:transparent;
}

.sheet{margin-top:10px;overflow-x:auto;background:var(--paper)}
.sheet svg{width:100%;height:auto;display:block}
.sheet.zoomed{overflow:auto;max-height:78vh;border:1px solid var(--rule);resize:vertical;cursor:grab;contain:layout paint}
.sheet.zoomed svg{max-width:none}
.sheet.dragging{cursor:grabbing}
.sheet.zoomed svg{user-select:none;-webkit-user-drag:none}

.row-btns{display:flex;gap:8px;flex-wrap:wrap}
.btn{
  font-family:"Saira Condensed",sans-serif;font-weight:700;font-size:14.9px;
  letter-spacing:.08em;text-transform:uppercase;padding:9px 14px;border-radius:2px;
  cursor:pointer;border:1px solid var(--copper);background:var(--copper);color:#fff;
  text-decoration:none;display:inline-block;text-align:center;
}
.btn:hover{background:var(--copper-lift);border-color:var(--copper-lift)}
.btn.ghost{background:transparent;color:var(--copper)}
.btn.ghost:hover{background:var(--treated);color:var(--copper)}
/* Shared 3D viewbar (src/shared/viewbar.ts): torch's 3D tab shows Exposure + Reset view,
   plus the Play-assembly button slotted in as an extra. Centered under the model. */
.viewbar{display:flex;align-items:center;justify-content:center;gap:16px;margin-top:12px;flex-wrap:wrap}
.viewbar .vb-range{display:inline-flex;align-items:center;gap:8px;font-size:13px;color:var(--ink-soft)}
.viewbar .vb-range input{width:120px;accent-color:var(--copper)}
.viewbar .vb-reset{font:inherit;font-size:12.6px;padding:5px 12px;border:1px solid var(--rule);background:var(--paper);color:var(--ink-soft);cursor:pointer;border-radius:2px}
.viewbar .vb-reset:hover{border-color:var(--copper);color:var(--ink)}
.viewbar .vb-btn{font-family:"Saira Condensed",sans-serif;font-weight:700;font-size:13px;letter-spacing:.06em;text-transform:uppercase;padding:5px 12px;border-radius:2px;cursor:pointer;border:1px solid var(--copper);background:var(--copper);color:#fff}
.viewbar .vb-btn:hover{background:var(--copper-lift);border-color:var(--copper-lift)}
/* "Essential" badge on a must-have shopping item (src/shared/shop.ts). */
.shop-essential{display:inline-block;margin-left:8px;font-family:"Saira Condensed",sans-serif;font-weight:700;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:#fff;background:var(--copper);padding:1px 7px;border-radius:2px;vertical-align:middle}

/* ---------- warnings ---------- */
.warnings{margin-top:22px;border-top:1px solid var(--rule);padding-top:14px}
.warnings:empty{display:none}
.warn-item{display:flex;gap:10px;padding:7px 0;font-size:15.5px;align-items:flex-start}
.warn-item b{
  flex:0 0 auto;font-family:"Saira Condensed",sans-serif;font-weight:700;font-size:12.1px;
  letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;margin-top:2px;
}
.warn-item.required b{background:var(--stamp);color:#fff}
.warn-item.caution b{background:var(--amber);color:#fff}
.warn-item.info b{background:var(--treated-deep);color:var(--ink-soft)}
.warn-item p{margin:0;color:var(--ink-soft)}

/* Education tab (HTML content in the sheet pane). */
.doc-page{padding:10px 6px 20px;max-width:70ch}
.doc-page h2{
  font-family:"Saira Condensed",sans-serif;font-weight:800;font-size:28px;
  letter-spacing:.01em;margin:0 0 6px;color:var(--ink);border:none;padding:0;text-transform:none;
}
.doc-page h3{
  font-family:"Saira Condensed",sans-serif;font-weight:700;font-size:15px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);
  margin:20px 0 4px;padding-top:12px;border-top:1px solid var(--rule);
}
.doc-page p{margin:8px 0 0;line-height:1.55;color:var(--ink-soft)}
.doc-page a{color:var(--copper);text-decoration:underline;text-underline-offset:2px;overflow-wrap:anywhere}
/* Latches build guide (fetched from latches.json). Sections carry an id for
   deep-links; images are optional and degrade to their caption when absent. */
.doc-page.latches .entry{scroll-margin-top:16px}
.doc-page.latches .standfirst{font-size:17px;line-height:1.45;color:var(--ink);font-weight:600;margin:12px 0 0}
.doc-page.latches .subhead{font-family:"Saira Condensed",sans-serif;font-weight:700;font-size:17px;color:var(--ink);margin:18px 0 0}
.doc-page.latches .shot{margin:14px 0 0}
.doc-page.latches .shot img{display:block;max-width:100%;height:auto;border:1px solid var(--rule);border-radius:3px}
.doc-page.latches .shot figcaption{margin:6px 0 0;font-size:13.5px;color:var(--ink-faint)}

/* Shopping / parts list: the shared affiliate catalog (src/shared/shop.ts), same as the
   box and marble tabs. One row per item, store links grouped right; wrap on a narrow screen. */
.shop-list{list-style:none;margin:14px 0 0;padding:0}
.shop-item{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 12px;
  padding:9px 0;border-top:1px solid var(--rule)}
.shop-item:first-child{border-top:none}
.shop-name{font-weight:600;color:var(--ink)}
.shop-note{font-size:13px;color:var(--ink-faint)}
.shop-buy{margin-left:auto;display:flex;align-items:baseline;gap:8px;white-space:nowrap}
.shop-store{color:var(--copper);text-decoration:underline;text-underline-offset:2px;font-size:14px}
.shop-sep{color:var(--ink-faint)}
.shop-disclosure{margin-top:16px;font-size:13px;color:var(--ink-faint)}

.blocked{padding:34px 24px;text-align:center;background:var(--treated)}
.blocked h3{font-family:"Saira Condensed",sans-serif;font-weight:700;font-size:21.8px;text-transform:uppercase;letter-spacing:.06em;margin:0 0 8px;color:var(--stamp)}
.blocked p{max-width:46ch;margin:0 auto;color:var(--ink-soft);font-size:16.1px}

[hidden]{display:none!important}
.foot{padding:26px 20px 44px;color:var(--ink-faint);font-size:14.9px;max-width:70ch}
.foot p{margin:0 0 6px}
.tiny{font-size:13.2px}

@media (max-width:900px){
  .layout{grid-template-columns:1fr}
  .controls{position:static;max-height:none}
}

/* ============================================================================
   ENGINEERING-PAPER FRAME  (design/engineering-paper branch)

   The "shop drawing on green engineering paper" look from the Claude design
   system in Design/Garden planter design system/. Shared verbatim with
   site/planner.css: the two tools carry the same tokens and control classes, so
   this block is identical there. Type is left alone; the identity is the frame.
   Placed BEFORE the print block below so print stays white (the print rule's
   `background:#fff` shorthand clears the grid image).
   ========================================================================== */

:root{
  --paper:#FBFCF7;   /* panel + sheet interior: warm near-white drawing stock */
  --rule:#A7B6A9;    /* hairline, nudged toward the system's green-grey line */
  --eng-ink:#16241c; /* structural ink line */
}

body{
  background-color:#E7EDDD;
  background-image:
    linear-gradient(rgba(58,96,66,.07) 1px,transparent 1px),
    linear-gradient(90deg,rgba(58,96,66,.07) 1px,transparent 1px),
    linear-gradient(rgba(58,96,66,.14) 1px,transparent 1px),
    linear-gradient(90deg,rgba(58,96,66,.14) 1px,transparent 1px);
  background-size:14px 14px,14px 14px,70px 70px,70px 70px;
  background-attachment:fixed;
}

.panel{border-color:var(--eng-ink);border-radius:0}
select,textarea{border-color:var(--eng-ink);border-radius:0}
.seg button,.btn,.beds li,.beds li .tag,.tab-panel,.warn-item b,.blocked{border-radius:0}
.sheet.zoomed,model-viewer.viewer3d{border-radius:0;border-color:var(--eng-ink)}

.masthead{background:transparent;border-bottom:3px double var(--eng-ink);
  position:relative;overflow:hidden}
.mast-inner{position:relative}
.mast-watermark{position:absolute;right:-30px;top:auto;bottom:-46px;width:230px;height:230px;
  opacity:.13;pointer-events:none}
.mast-brand{display:flex;align-items:center;gap:16px}
.mast-brand svg{flex:none}

.controls h2{display:flex;align-items:center;gap:9px}
.controls h2 svg{width:16px;height:16px;flex:none}

.seg button[aria-pressed=true]{box-shadow:2px 2px 0 var(--eng-ink);border-color:var(--eng-ink)}
.seg button:disabled{border-style:dashed;color:var(--rule);background:var(--paper)}

.btn{border-radius:0}
.btn:not(.ghost){box-shadow:2px 2px 0 var(--eng-ink)}
.btn:not(.ghost):active{box-shadow:0 0 0 var(--eng-ink);transform:translate(2px,2px)}
.btn.ghost{border-color:var(--eng-ink);color:var(--copper)}

.tabs{gap:2px;border-bottom:1px solid var(--eng-ink)}
.tabs button{border:1px solid var(--rule);border-bottom:none;
  background:rgba(255,255,255,.5);border-radius:0}
.tabs button:hover{background:rgba(255,255,255,.8)}
.tabs button[aria-selected=true]{background:var(--eng-ink);color:var(--paper);
  border-color:var(--eng-ink);margin-bottom:-1px;display:inline-flex;align-items:center;gap:7px}
.tabs button[aria-selected=true]::before{content:"";width:13px;height:13px;flex:none;
  background:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23A8C27E'%20stroke-width='1.8'%3E%3Ccircle%20cx='12'%20cy='12'%20r='9.6'%20stroke-dasharray='2.6%203.4'/%3E%3Ccircle%20cx='12'%20cy='12'%20r='5'/%3E%3C/svg%3E") no-repeat center/contain}
.tabs button:disabled::before{display:none}

.sheet{background-color:var(--paper);
  background-image:
    linear-gradient(rgba(58,96,66,.075) 1px,transparent 1px),
    linear-gradient(90deg,rgba(58,96,66,.075) 1px,transparent 1px);
  background-size:16px 16px}

/* Print: just the drawing, at its natural size. */
@media print{
  body{background:#fff}
  .masthead,.controls,.tabs,.zoombar,.buy,.warnings,.foot{display:none!important}
  .layout{display:block;padding:0}
  .panel{border:none;padding:0}
  .sheet{overflow:visible;background:#fff}
  .sheet svg{width:auto;max-width:100%}
}

/* ---- marble-escape additions ---- */
/* Lists in the build guide (the box tool never used ul/ol in a doc-page). */
.doc-page .standfirst{font-size:16px;line-height:1.5;color:var(--ink);font-weight:600;margin:10px 0 0}
.doc-page ul,.doc-page ol{margin:8px 0 0;padding-left:20px;color:var(--ink-soft);line-height:1.6}
.doc-page li{margin:3px 0}
.doc-page ul.materials{list-style:square}
.doc-page .tiny{margin:12px 0 0;font-size:12.5px;color:var(--ink-faint)}

/* A plain checkbox row for the on-path-holes toggle. */
.check{display:flex;align-items:flex-start;gap:8px}
.check input{margin-top:3px;width:16px;height:16px;accent-color:var(--copper)}
.check label{margin:0;font-weight:600}

/* The generate/download actions, standing in for the box tool's Buy PDF. */
.actions{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end}
.actions .btn{padding:10px 16px}

/* Seed stepper: +/- buttons flanking the slider, since the seed range is too
   fine to land on by dragging alone. */
.seed-row{display:flex;align-items:center;gap:8px}
.seed-row input[type=range]{flex:1;min-width:0}
.step{
  flex:none;width:30px;height:30px;line-height:1;font-size:18px;font-weight:600;
  border:1px solid var(--rule);background:var(--paper);color:var(--ink);
  cursor:pointer;border-radius:0;padding:0;
}
.step:hover{border-color:var(--copper);color:var(--copper)}
.step:active{background:var(--treated)}

/* Reserve the scrollbar gutter and hold a stable sheet height. Without these the
   page width and height jump as each new maze changes the drawing's size, which
   shifts the whole layout and made dragging a control feel like a moving target. */
html{scrollbar-gutter:stable}
.output .sheet{min-height:480px}

/* Play tab: the canvas mini-game (marble-play.js). */
.play-wrap{display:flex;flex-direction:column;gap:10px;padding:6px 2px 12px}
.play-hud{display:flex;align-items:center;justify-content:space-between;gap:12px}
.play-hud #playStat{font-family:"IBM Plex Mono",monospace;font-size:14px;color:var(--ink-soft)}
#playCanvas{display:block;max-width:100%;background:var(--paper);border:1px solid var(--rule);touch-action:none;cursor:crosshair}
.play-tip{margin:2px 0 0}
.play-msg{margin:4px 0 0;padding:10px 12px;background:var(--treated);border:1px solid var(--rule);
  font-weight:600;color:var(--ink)}
.play-hud .play-btns{display:flex;gap:8px;flex:none}

/* ================= static build guide (torch) ================= */
/* The torch has no controls panel; it is a single flowing document rendered by
   src/shared/build-guide.ts. These rules dress the guide classes that renderer emits. */
.guide-main{padding:22px 20px 10px}
.guide-host{max-width:80ch}
.doc-page.guide h2{
  font-family:"Saira Condensed",sans-serif;font-weight:800;text-transform:uppercase;
  letter-spacing:-.01em;font-size:clamp(26px,4.5vw,40px);line-height:.95;margin:0 0 6px;
}
.doc-page.guide h3{
  font-family:"Saira Condensed",sans-serif;font-weight:700;text-transform:uppercase;
  letter-spacing:.01em;font-size:22px;margin:28px 0 10px;color:var(--ink);
  border-bottom:1px solid var(--rule);padding-bottom:5px;
}
.doc-page.guide h4{font-size:18px;margin:0 0 6px;color:var(--ink)}
.doc-page.guide h5{font-size:15px;margin:12px 0 4px;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.03em}
.doc-page.guide p{margin:0 0 10px;color:var(--ink-soft)}
.standfirst{font-size:1.12em;color:var(--ink-soft);margin:0 0 16px;max-width:62ch}
.intro{margin:8px 0 4px}

/* 3D hero */
.guide-hero{margin:8px 0 20px}
.viewer3d{display:block;width:100%;height:min(58vh,520px);background:var(--board);border:1px solid var(--board-edge);border-radius:6px}

/* numbered assembly steps */
ol.steps{list-style:none;counter-reset:step;margin:0;padding:0}
ol.steps>li.gstep{counter-increment:step;position:relative;padding:2px 0 16px 46px;margin:0 0 14px;border-bottom:1px dashed var(--rule)}
ol.steps>li.gstep:last-child{border-bottom:0}
ol.steps>li.gstep::before{
  content:counter(step);position:absolute;left:0;top:0;
  width:32px;height:32px;border-radius:50%;background:var(--copper);color:#fff;
  font-family:"Saira Condensed",sans-serif;font-weight:800;font-size:18px;
  display:flex;align-items:center;justify-content:center;
}

/* photos, with graceful degrade to the caption if the image is missing */
figure.shot{margin:12px 0;border:1px solid var(--rule);border-radius:4px;overflow:hidden;background:var(--paper)}
figure.shot img{display:block;width:100%;height:auto}
figure.shot figcaption{padding:6px 10px;font-size:14px;color:var(--ink-faint)}
figure.shot.no-img{padding:14px;border-style:dashed;color:var(--ink-faint);font-size:14px}
figure.shot.no-img figcaption{padding:0}

/* materials / affiliate list */
ul.materials{list-style:none;margin:6px 0 4px;padding:0}
ul.materials>li{padding:8px 0;border-bottom:1px solid var(--rule);color:var(--ink-soft)}
ul.materials>li:last-child{border-bottom:0}
.mat-name{font-weight:600;color:var(--ink)}
ul.materials .buy{display:inline-flex;gap:6px;flex-wrap:wrap;margin-left:6px}
ul.materials .buy a{
  display:inline-block;padding:2px 10px;border:1px solid var(--copper);border-radius:999px;
  color:var(--copper);text-decoration:none;font-size:14px;white-space:nowrap;
}
ul.materials .buy a:hover{background:var(--copper);color:#fff}
.doc-page.guide .tiny{font-size:13px;color:var(--ink-faint);margin-top:8px}
/* ---------- home button (upper-right of the masthead, to the landing hub) ---------- */
.mast-inner{position:relative}
.home-btn{
  position:absolute;top:14px;right:16px;z-index:3;
  display:inline-flex;align-items:center;gap:7px;
  padding:8px 15px;border:1px solid var(--copper,#1d6b58);border-radius:999px;
  background:var(--paper,#fff);color:var(--copper,#1d6b58);
  text-decoration:none;font-weight:700;font-size:13.5px;letter-spacing:.02em;line-height:1;
  box-shadow:0 1px 0 rgba(22,34,28,.05);
  transition:background .16s ease,color .16s ease,transform .16s ease,box-shadow .16s ease;
}
.home-btn:hover,.home-btn:focus-visible{
  background:var(--copper,#1d6b58);color:#fff;outline:none;
  transform:translateY(-1px);box-shadow:0 8px 18px -8px rgba(22,34,28,.4);
}
.home-btn svg{width:16px;height:16px;transition:transform .2s ease}
.home-btn:hover svg{transform:rotate(-12deg)}

/* tabbed guide panels */
.tab-panel{padding-top:18px}
.links-callout{background:var(--treated);border:1px solid var(--rule);border-radius:4px;padding:10px 14px;margin:0 0 16px}
.links-callout h4{margin:0 0 6px;font-size:13px;text-transform:uppercase;letter-spacing:.03em;color:var(--ink-soft)}
ul.links{list-style:none;margin:0;padding:0}
ul.links>li{padding:3px 0;color:var(--ink-soft)}
ul.links a{color:var(--copper);font-weight:600}

/* ================= builds gallery (shared renderer, src/shared/gallery.ts) ========= */
.gallery .standfirst{max-width:70ch}
.ggrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px;margin-top:14px}
.gtile{display:block;border:1px solid var(--rule);border-radius:4px;overflow:hidden;text-decoration:none;background:var(--paper);color:inherit;transition:transform .14s ease,box-shadow .14s ease,border-color .14s ease}
.gtile:hover,.gtile:focus-visible{transform:translateY(-3px);box-shadow:0 10px 22px -12px rgba(22,34,28,.4);border-color:var(--copper);outline:none}
.gtile img{display:block;width:100%;height:170px;object-fit:cover;background:var(--treated)}
.gtile-cap{display:block;padding:7px 10px;font-size:13px;color:var(--ink-soft)}
.gtile-cap .gcredit{color:var(--ink-faint);margin-left:5px}

/* pure-CSS :target lightbox */
.glightbox{display:none;position:fixed;inset:0;z-index:100;background:rgba(16,22,20,.85);align-items:center;justify-content:center;padding:24px}
.glightbox:target{display:flex}
.glightbox .gback{position:absolute;inset:0;z-index:0;cursor:zoom-out}
.glightbox .gx{position:absolute;top:12px;right:18px;z-index:2;color:#f2ece0;font-size:32px;line-height:1;text-decoration:none;opacity:.85}
.glightbox .gx:hover{opacity:1}
.glightbox figure{position:relative;z-index:1;margin:0;max-width:min(1100px,94vw);display:flex;flex-direction:column;align-items:center}
.glightbox figure img{max-width:100%;max-height:82vh;object-fit:contain;border-radius:4px;background:#fff}
.glightbox figcaption{color:#f2ece0;padding:10px 4px 0;font-size:14px;text-align:center}
