/* netlld shared design system — used by both the builder (index.html) and the design workshop (workshop.html) */
:root{
  /* One accent, used deliberately. The old blue->purple gradient read as
     decoration; enterprise software earns trust by being quiet. */
  --bg:#f7f9fc; --bg-soft:#f1f5fb; --surface:#ffffff; --surface-2:#f6f8fc;
  --line:#e4e9f2; --line-soft:#eef1f7;
  --ink:#0f1b2d; --muted:#54627c; --dim:#8492aa;
  --brand:#2563eb; --brand-ink:#1d4ed8; --brand-wash:#eff4ff;
  --brand-2:#2563eb;                  /* kept so old rules resolve to the accent */
  --teal:#0f9488; --amber:#b45309; --red:#dc2626; --green:#0e9f6e;
  --grad: var(--brand);               /* legacy hook, now flat */
  --radius:16px; --radius-sm:10px;
  --shadow: 0 1px 2px rgba(15,27,45,.04), 0 8px 24px -16px rgba(15,27,45,.12);
  --shadow-lift: 0 2px 4px rgba(15,27,45,.05), 0 18px 40px -22px rgba(15,27,45,.22);
  --display:'Plus Jakarta Sans','Inter',-apple-system,Segoe UI,sans-serif;
  color-scheme: light;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; color:var(--ink); background:var(--bg);
  font-family:'Inter',-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
  -webkit-font-smoothing:antialiased;
}
code,.mono{font-family:'JetBrains Mono',ui-monospace,Consolas,monospace}

/* ---------- header ---------- */
header.top{
  position:sticky; top:0; z-index:20;
  display:flex; align-items:center; gap:14px; justify-content:space-between;
  padding:14px 32px; background:rgba(255,255,255,.9); backdrop-filter:saturate(180%) blur(12px);
  border-bottom:1px solid var(--line);
}
.brand{display:flex; align-items:center; gap:11px}
.brand .mark{
  width:34px; height:34px; border-radius:10px; background:var(--brand);
  display:flex; align-items:center; justify-content:center; font-weight:700; font-size:15px; color:#fff;
}
.brand .name{font-family:var(--display); font-weight:700; font-size:17px; letter-spacing:-.02em}
.brand .tag{color:var(--muted); font-size:12.5px; margin-top:1px}
.hdr-right{display:flex; align-items:center; gap:10px; color:var(--dim); font-size:12.5px}
.pill{display:inline-flex; align-items:center; gap:6px; padding:5px 11px; border-radius:99px; background:var(--surface); border:1px solid var(--line); font-size:12px; color:var(--muted)}
.pill .dot{width:6px; height:6px; border-radius:50%; background:var(--green); box-shadow:0 0 0 3px rgba(62,207,142,.18)}
.navlink{display:inline-flex; align-items:center; gap:6px; padding:8px 15px; border-radius:9px; background:transparent; border:1px solid transparent; font-size:13px; font-weight:600; color:var(--muted); text-decoration:none; transition:color .15s, background .15s}
.navlink:hover{color:var(--brand); background:var(--brand-wash)}

/* ---------- layout ---------- */
.wrap{max-width:1180px; margin:0 auto; padding:0 20px 88px; display:flex; flex-direction:column; gap:26px}

/* Hero: one clear claim, one action, and the facts that back it. */
.hero{padding:56px 0 10px; display:grid; grid-template-columns:1.05fr .95fr; gap:52px; align-items:center}
.hero-copy{display:flex; flex-direction:column; align-items:flex-start; gap:18px}
.hero-shot{margin:0; background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:var(--shadow-lift); padding:20px 20px 14px; overflow:hidden}
.hero-shot img{display:block; width:100%; height:auto}
.hero-shot figcaption{margin-top:12px; padding-top:12px; border-top:1px solid var(--line-soft);
  color:var(--dim); font-size:12.5px; line-height:1.45}
@media (max-width:900px){ .hero{grid-template-columns:1fr; gap:34px; padding-top:38px} }
.hero .eyebrow, .herofilm .eyebrow{display:inline-flex; align-items:center; gap:8px; padding:6px 14px; border-radius:99px;
  background:var(--brand-wash); color:var(--brand-ink); border:1px solid #dbe6fe;
  font-size:12.5px; font-weight:600; letter-spacing:.01em}
.hero h1, .herofilm h1{font-family:var(--display); font-size:clamp(31px,3.9vw,46px); font-weight:800; line-height:1.08;
  letter-spacing:-.035em; margin:0; max-width:15ch; text-wrap:balance}
.hero h1 span, .herofilm h1 span{color:var(--brand)}
.hero p, .herofilm p{color:var(--muted); margin:0; font-size:16.5px; max-width:52ch; line-height:1.6}
.hero-cta{display:flex; flex-wrap:wrap; gap:12px; margin-top:4px}
.trustbar{display:flex; flex-wrap:wrap; justify-content:center; gap:12px 36px; margin:4px auto 0;
  padding-top:24px; border-top:1px solid var(--line); width:100%; max-width:960px}
.trustbar div{display:flex; align-items:center; gap:8px; color:var(--dim); font-size:13.5px;
  white-space:nowrap}
.trustbar b{color:var(--ink); font-weight:600}
@media (max-width:760px){ .trustbar{flex-direction:column; align-items:flex-start;
  max-width:340px; margin-inline:auto; gap:10px} }
.trustbar b{color:var(--ink); font-weight:600}
.trustbar .tick{color:var(--green); font-weight:700}
@media (max-width:620px){ .hero{padding:36px 0 4px} .hero p, .herofilm p{font-size:15.5px} }

.card{background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow); overflow:hidden}
.card:has(.tabs){box-shadow:var(--shadow-lift)}
.card .hd{padding:18px 26px; border-bottom:1px solid var(--line-soft); font-weight:700; display:flex; align-items:center; justify-content:space-between; gap:10px}
.card .hd .t{display:flex; align-items:center; gap:9px; font-size:14.5px}
.card .bd{padding:28px}

/* ---------- tabs ---------- */
.tabs{display:flex; gap:4px; padding:10px 10px 0; background:var(--bg-soft)}
.tab{
  display:flex; align-items:center; gap:8px; padding:12px 18px; border-radius:10px 10px 0 0; cursor:pointer;
  font-weight:600; font-size:13.5px; color:var(--dim); border:1px solid transparent; border-bottom:none;
  transition:color .15s, background .15s;
}
.tab .ic{font-size:15px; opacity:.85}
.tab:hover{color:var(--muted)}
.tab.active{color:var(--ink); background:var(--surface); border-color:var(--line)}
.pane{display:none; padding:26px}
.pane.active{display:block; animation:fade .25s ease}
@keyframes fade{from{opacity:0; transform:translateY(3px)} to{opacity:1; transform:none}}

.lede{color:var(--muted); font-size:13.5px; line-height:1.55; margin:0 0 18px}
.lede strong{color:var(--ink)}

label{display:block; font-size:11px; text-transform:uppercase; letter-spacing:.6px; color:var(--dim); margin:0 0 6px; font-weight:600}
input[type=text],input[type=number]{
  width:100%; padding:10px 12px; border:1px solid var(--line); border-radius:var(--radius-sm); font-size:13.5px;
  background:var(--bg-soft); color:var(--ink); transition:border-color .15s, box-shadow .15s;
}
input[type=text]:focus,input[type=number]:focus{outline:none; border-color:var(--brand); box-shadow:0 0 0 3px rgba(91,141,255,.18)}
input[type=color]{width:100%; height:40px; padding:3px; border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--bg-soft); cursor:pointer}
select{
  width:100%; padding:10px 12px; border:1px solid var(--line); border-radius:var(--radius-sm); font-size:13.5px;
  background:var(--bg-soft); color:var(--ink); cursor:pointer; transition:border-color .15s, box-shadow .15s;
}
select:focus{outline:none; border-color:var(--brand); box-shadow:0 0 0 3px rgba(67,104,224,.15)}
.qbuild{
  border:1px solid rgba(67,104,224,.25); border-radius:var(--radius-sm); padding:16px;
  background:linear-gradient(135deg, rgba(67,104,224,.05), rgba(124,92,255,.04)); margin-bottom:4px;
}
.qbuild-actions{display:flex; gap:10px; margin-top:12px; flex-wrap:wrap}
.row{display:grid; gap:12px; margin-bottom:12px; align-items:end}
.grid2{grid-template-columns:1fr 1fr} .grid3{grid-template-columns:1fr 1fr 1fr} .grid4{grid-template-columns:1fr 1fr 1fr 1fr}
.subhd{
  display:flex; align-items:baseline; gap:10px; font-weight:700; color:var(--ink); margin:28px 0 12px; font-size:14px;
  border-top:1px solid var(--line-soft); padding-top:20px;
}
.subhd .hint{font-weight:500}
.rowbox{border:1px solid var(--line); border-radius:var(--radius-sm); padding:14px; margin-bottom:10px; background:var(--bg-soft)}
.rowline{display:grid; gap:10px; align-items:end}
button{cursor:pointer; font:inherit}
.btn{
  background:var(--brand); color:#fff; border:none; border-radius:10px; padding:12px 22px; font-weight:600; font-size:14px;
  box-shadow:0 1px 2px rgba(37,99,235,.24); transition:background .15s;
}
.btn:hover{background:var(--brand-ink)}
.btn.big{padding:14px 26px; font-size:15px}
.btn.lg{padding:15px 30px; font-size:16px; border-radius:11px}
.btn:disabled{opacity:.55; cursor:progress; transform:none}
.btn.ghost{background:var(--surface); color:var(--ink); border:1px solid var(--line); box-shadow:none}
.btn.ghost:hover{background:var(--surface-2); border-color:#cfd9ea}
.addbtn{background:var(--surface-2); color:var(--brand); border:1px dashed #b7c4e8; border-radius:var(--radius-sm); padding:9px 14px; font-weight:600; font-size:12.5px}
.addbtn:hover{border-color:var(--brand)}
.del{background:transparent; border:1px solid var(--line); color:var(--red); border-radius:var(--radius-sm); padding:7px 11px; font-size:12.5px}
.hint{color:var(--dim); font-size:12px; margin:2px 0 0}
.drop{border:2px dashed #c3cfec; border-radius:var(--radius); padding:44px; text-align:center; color:var(--muted); background:var(--bg-soft); transition:border-color .15s, background .15s}
.drop.drag{background:rgba(67,104,224,.06); border-color:var(--brand)}
.pastebox{width:100%; padding:10px 12px; border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--bg-soft); color:var(--ink); font:12.5px/1.5 'JetBrains Mono', Consolas, monospace; resize:vertical}
.pastebox:focus{outline:none; border-color:var(--brand); box-shadow:0 0 0 3px rgba(91,141,255,.18)}
.drop .icon{font-size:30px; margin-bottom:10px; opacity:.85}

.spin{display:none; align-items:center; gap:12px; color:var(--muted); margin-top:16px; font-size:13.5px}
.spin.on{display:flex}
.loader{width:18px; height:18px; border:3px solid var(--line); border-top-color:var(--brand); border-radius:50%; animation:sp .8s linear infinite}
@keyframes sp{to{transform:rotate(360deg)}}
.err{background:rgba(197,51,86,.07); border:1px solid rgba(197,51,86,.28); color:#a72246; border-radius:var(--radius-sm); padding:13px 16px; margin-top:16px; display:none; font-size:13.5px}

/* ---------- results ---------- */
#results{display:none}
.execsum{
  background:linear-gradient(135deg, rgba(67,104,224,.07), rgba(124,92,255,.05));
  border:1px solid rgba(67,104,224,.2); border-radius:var(--radius-sm); padding:16px 18px; margin-bottom:20px;
  font-size:13.5px; line-height:1.6; color:var(--muted);
}
.execsum b{color:var(--ink)}
.stats{display:grid; grid-template-columns:repeat(6,1fr); gap:10px; margin-bottom:20px}
.stat{background:var(--bg-soft); border:1px solid var(--line); border-radius:var(--radius-sm); padding:12px 14px}
.stat .k{display:block; font-size:10px; text-transform:uppercase; letter-spacing:.6px; color:var(--dim); margin-bottom:4px}
.stat .v{font-size:21px; font-weight:800; color:var(--ink)}

.section-title{font-size:12px; text-transform:uppercase; letter-spacing:.6px; color:var(--dim); font-weight:700; margin:22px 0 10px; display:flex; align-items:center; gap:8px}
.section-title .line{flex:1; height:1px; background:var(--line-soft)}

.findbar{display:flex; gap:10px; margin-bottom:12px}
.fchip{display:flex; align-items:center; gap:8px; padding:9px 14px; border-radius:var(--radius-sm); font-size:13px; font-weight:700; border:1px solid var(--line)}
.fchip.crit{background:rgba(197,51,86,.07); border-color:rgba(197,51,86,.25); color:#a72246}
.fchip.warn{background:rgba(184,114,10,.08); border-color:rgba(184,114,10,.25); color:#8f5a08}
.fchip.clean{background:rgba(26,156,103,.08); border-color:rgba(26,156,103,.25); color:#127a51}
.finding{display:flex; gap:12px; align-items:flex-start; padding:11px 13px; border-radius:var(--radius-sm); border:1px solid var(--line-soft); background:var(--bg-soft); margin-bottom:7px; font-size:13px}
.finding .sev{flex:0 0 auto; width:8px; height:8px; border-radius:50%; margin-top:5px}
.finding .sev.critical{background:var(--red)} .finding .sev.warning{background:var(--amber)} .finding .sev.info{background:var(--dim)}
.finding .cat{color:var(--dim); font-size:10.5px; text-transform:uppercase; letter-spacing:.5px; font-weight:700; margin-bottom:2px}
.finding .subj{color:var(--ink); font-weight:600; margin-right:6px}
.finding .det{color:var(--muted)}
.emptyfind{padding:14px 16px; border-radius:var(--radius-sm); background:rgba(26,156,103,.06); border:1px solid rgba(26,156,103,.22); color:#127a51; font-size:13.5px; display:flex; align-items:center; gap:10px}

.bomtable{width:100%; border-collapse:collapse; font-size:13px; margin-bottom:16px}
.bomtable th{text-align:left; color:var(--dim); font-size:10.5px; text-transform:uppercase; letter-spacing:.5px; padding:8px 12px; border-bottom:1px solid var(--line)}
.bomtable td{padding:10px 12px; border-bottom:1px solid var(--line-soft); color:var(--ink)}
.bomtable tr:last-child td{border-bottom:none}
.bomtable .role{display:inline-block; padding:2px 8px; border-radius:99px; font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.4px}
.role.spine{background:rgba(67,104,224,.1); color:#2c4bb8}
.role.leaf{background:rgba(124,92,255,.1); color:#6b46c9}
.portgrid{display:grid; grid-template-columns:repeat(4,1fr); gap:10px}
.portstat{background:var(--bg-soft); border:1px solid var(--line-soft); border-radius:var(--radius-sm); padding:10px 12px; text-align:center}
.portstat .v{font-size:17px; font-weight:800; color:var(--teal)}
.portstat .k{font-size:10.5px; color:var(--dim); margin-top:2px}

.diaggrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:12px; margin-bottom:6px}
.diagcard{border:1px solid var(--line); border-radius:var(--radius-sm); overflow:hidden; background:var(--bg-soft)}
.diagcard img{width:100%; display:block; background:#fff}
.diagcard .cap{padding:8px 10px; font-size:11.5px; color:var(--muted); text-transform:capitalize; border-top:1px solid var(--line-soft)}

.dlbar{display:flex; gap:10px; flex-wrap:wrap; margin:18px 0 20px}
.dl{display:inline-flex; align-items:center; gap:8px; background:var(--surface-2); color:var(--ink); border:1px solid var(--line); border-radius:10px; padding:11px 18px; font-weight:600; font-size:13px; text-decoration:none; transition:border-color .15s, transform .12s}
.dl:hover{border-color:var(--brand); transform:translateY(-1px)}
.dl.primary{background:var(--grad); color:#fff; border:none; box-shadow:0 10px 24px -10px rgba(67,104,224,.5)}

.previewwrap{border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; background:#fff}
.previewwrap .pbar{background:var(--bg-soft); color:var(--dim); font-size:11.5px; padding:8px 14px; border-bottom:1px solid var(--line); display:flex; justify-content:space-between}
iframe.preview{width:100%; height:740px; border:0; display:block}

::-webkit-scrollbar{width:10px; height:10px}
::-webkit-scrollbar-thumb{background:var(--line); border-radius:6px}
::-webkit-scrollbar-track{background:transparent}

@media (max-width:820px){
  .stats{grid-template-columns:repeat(2,1fr)}
  .portgrid{grid-template-columns:repeat(2,1fr)}
  .grid4,.grid3,.grid2{grid-template-columns:1fr}
}

/* ---------- design workshop wizard -- used both standalone (workshop.html) and as a tab (index.html) ---------- */
.wprogress{display:flex; align-items:center; gap:6px; padding:18px 24px 4px}
.wdot{flex:1; height:5px; border-radius:99px; background:var(--line-soft); transition:background .2s}
.wdot.done{background:var(--teal)}
.wdot.current{background:var(--brand)}
.wstepnum{color:var(--dim); font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:.6px; padding:0 24px; margin-top:10px}
.wstep{display:none; padding:22px 26px 8px}
.wstep.active{display:block; animation:fade .25s ease}
.wq{font-size:19px; font-weight:800; letter-spacing:-.01em; margin:0 0 6px}
.wq-hint{color:var(--muted); font-size:13.5px; line-height:1.55; margin:0 0 22px; max-width:620px}
.wnav{display:flex; justify-content:space-between; align-items:center; padding:18px 26px 26px; gap:10px}
.wwarn{background:rgba(184,114,10,.08); border:1px solid rgba(184,114,10,.25); color:#8f5a08; border-radius:var(--radius-sm); padding:11px 14px; font-size:13px; display:none; margin-top:14px}
.envrow{margin-bottom:8px}
.rev-row{display:flex; justify-content:space-between; gap:20px; padding:10px 0; border-bottom:1px solid var(--line-soft); font-size:13.5px}
.rev-row:last-child{border-bottom:none}
.rev-row span{color:var(--dim)}
.rev-row b{color:var(--ink); text-align:right}
.chooser{display:grid; grid-template-columns:1fr 1fr; gap:12px}
.chooser label.opt{
  display:flex; flex-direction:column; gap:4px; border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:14px 16px; cursor:pointer; background:var(--bg-soft); transition:border-color .15s, background .15s;
}
.chooser label.opt:has(input:checked){border-color:var(--brand); background:rgba(67,104,224,.06)}
.chooser label.opt .t{font-weight:700; font-size:13.5px; color:var(--ink); text-transform:none; letter-spacing:0}
.chooser label.opt .d{font-size:12px; color:var(--muted); font-weight:500}
@media (max-width:820px){ .chooser{grid-template-columns:1fr} }


/* ---------- marketing sections ---------- */
.sect-h{font-family:var(--display); font-size:clamp(22px,2.6vw,29px); font-weight:700;
  letter-spacing:-.025em; margin:0 0 8px; text-wrap:balance}
.sect-p{color:var(--muted); margin:0 0 26px; font-size:15.5px; max-width:66ch; line-height:1.6}
.ways, .compare, .limits{padding:14px 0 6px}

/* Four ways in. Numbered because they are genuinely enumerated options, not a sequence. */
.waygrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(232px,1fr)); gap:16px}
.way{background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:22px; display:flex; flex-direction:column; gap:7px}
.way-n{font-family:var(--mono,'JetBrains Mono',monospace); font-size:11.5px; font-weight:600;
  letter-spacing:.12em; color:var(--brand)}
.way h3{font-family:var(--display); font-size:16px; font-weight:700; margin:0; letter-spacing:-.01em}
.way p{margin:0; color:var(--muted); font-size:13.8px; line-height:1.55}
.way code{background:var(--brand-wash); color:var(--brand-ink); padding:1px 5px; border-radius:4px; font-size:12.5px}

/* Comparison. The honest column is the left one - AVD is free and from the vendor. */
.ctable-wrap{overflow-x:auto; background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius); box-shadow:var(--shadow)}
.ctable{width:100%; border-collapse:collapse; min-width:620px; font-size:13.8px}
.ctable th, .ctable td{padding:14px 18px; text-align:left; vertical-align:top;
  border-bottom:1px solid var(--line-soft)}
.ctable thead th{font-size:12px; letter-spacing:.06em; text-transform:uppercase; color:var(--dim);
  font-weight:600; background:var(--surface-2); border-bottom:1px solid var(--line)}
.ctable tbody th{font-weight:600; color:var(--ink); width:210px}
.ctable td{color:var(--muted)}
.ctable .me{background:var(--brand-wash)}
.ctable thead th.me{color:var(--brand-ink); background:#e4edff}
.ctable td.yes{color:var(--ink); font-weight:500}
.ctable td.no{color:var(--dim)}
.ctable tbody tr:last-child th, .ctable tbody tr:last-child td{border-bottom:none}

/* Limits. Flat, no cards - this section should read as candour, not a feature grid. */
.limitgrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(268px,1fr)); gap:18px 34px;
  padding-top:4px; border-top:1px solid var(--line)}
.limitgrid div{color:var(--muted); font-size:14px; line-height:1.6; padding-top:16px}
.limitgrid b{color:var(--ink); font-weight:600}


/* ---------- hero: the fabric drawing itself ---------- */
/* The diagram is netlld's own output, so it earns its motion by showing what
   the tool does: spines land, leaves land, then every uplink draws in. After
   that the links carry a slow pulse so the picture is alive but not busy. */
.shot-bar{display:flex; align-items:center; gap:6px; padding:0 2px 12px}
.shot-bar span{width:9px; height:9px; border-radius:50%; background:#e2e7f0}
.shot-bar span:nth-child(1){background:#f0b4b4}
.shot-bar span:nth-child(2){background:#f2d9a8}
.shot-bar span:nth-child(3){background:#bfe0c4}
.shot-bar em{margin-left:8px; font-family:'JetBrains Mono',monospace; font-style:normal;
  font-size:11.5px; color:var(--dim)}
.fabricstack{position:relative; display:grid}
.fabricview{grid-area:1/1; opacity:0; visibility:hidden; transition:opacity .45s ease}
.fabricview.live{opacity:1; visibility:visible}
.fabric-svg{display:block; width:100%; height:auto}

/* Only the visible diagram animates, so every switch redraws the fabric. */
.fabricview.live .node{ opacity:0; transform-box:fill-box; transform-origin:center;
  animation:nodeIn .5s cubic-bezier(.2,.7,.3,1) forwards;
  animation-delay:calc(var(--i) * 55ms); }
.fabricview.live .edge path{ stroke-dasharray:620; stroke-dashoffset:620;
  animation:edgeDraw 1s ease-out forwards, edgeFlow 5s linear 2.8s infinite;
  animation-delay:calc(800ms + var(--i) * 24ms), 2.8s; }

.shot-tag{margin-left:auto; font-size:11px; color:var(--dim); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; max-width:45%}
@media (max-width:1100px){ .shot-tag{display:none} }
.shot-dots{display:flex; gap:7px; justify-content:center; padding:12px 0 2px}
.shot-dots button{width:26px; height:4px; padding:0; border:none; border-radius:99px;
  background:#dce2ed; cursor:pointer; transition:background .3s, width .3s}
.shot-dots button.on{background:var(--brand); width:34px}
.shot-dots button:hover{background:#b9c5da}
.shot-dots button.on:hover{background:var(--brand)}
@keyframes nodeIn{ from{opacity:0; transform:scale(.72)} to{opacity:1; transform:scale(1)} }
@keyframes edgeDraw{ to{stroke-dashoffset:0} }
@keyframes edgeFlow{ from{stroke-dasharray:6 10; stroke-dashoffset:96} to{stroke-dasharray:6 10; stroke-dashoffset:0} }

/* Four steps, one lit at a time - what the tool is doing to that fabric. */
.pipeline{display:grid; grid-template-columns:repeat(4,1fr); gap:8px; list-style:none;
  margin:16px 0 0; padding:14px 0 0; border-top:1px solid var(--line-soft)}
.pipeline li{display:flex; flex-direction:column; gap:2px; padding:9px 10px; border-radius:8px;
  border:1px solid transparent; transition:background .4s, border-color .4s}
.pipeline b{font-size:12.5px; font-weight:600; color:var(--dim); transition:color .4s}
.pipeline span{font-size:11px; color:var(--dim); opacity:.75; line-height:1.35}
.pipeline li.on{background:var(--brand-wash); border-color:#dbe6fe}
.pipeline li.on b{color:var(--brand-ink)}
@media (max-width:1040px){ .pipeline{grid-template-columns:repeat(2,1fr)} }

@media (prefers-reduced-motion:reduce){
  .fabricview.live .node{opacity:1; animation:none}
  .fabricview.live .edge path{stroke-dasharray:none; stroke-dashoffset:0; animation:none}
  .fabricview{transition:none}
  .pipeline li{transition:none}
}


/* ---------- what one build produces ---------- */
/* Big-number tiles earn their place here: these figures are the point of the
   section, and every one is counted off the fabric rather than chosen. */
.produced{padding:14px 0 6px}
.countgrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(132px,1fr)); gap:1px;
  background:var(--line); border:1px solid var(--line); border-radius:var(--radius);
  overflow:hidden}
.count{background:var(--surface); padding:20px 18px; display:flex; flex-direction:column; gap:3px}
.count b{font-family:var(--display); font-size:30px; font-weight:800; letter-spacing:-.03em;
  color:var(--brand); font-variant-numeric:tabular-nums; line-height:1}
.count span{font-size:12.5px; color:var(--muted)}


/* ---------- flow diagrams ---------- */
.flows{padding:14px 0 6px}
.flowtabs{display:flex; flex-wrap:wrap; gap:8px; margin-bottom:14px}
.flowtabs button{padding:9px 16px; border-radius:99px; border:1px solid var(--line);
  background:var(--surface); color:var(--muted); font-size:13px; font-weight:600;
  cursor:pointer; transition:color .15s, border-color .15s, background .15s}
.flowtabs button:hover{border-color:#cfd9ea; color:var(--ink)}
.flowtabs button.on{background:var(--brand); border-color:var(--brand); color:#fff}
.flowstack{display:grid}
.flowview{grid-area:1/1; margin:0; opacity:0; visibility:hidden; transition:opacity .35s ease}
.flowview.live{opacity:1; visibility:visible}
.flowscroll{background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:20px; overflow-x:auto}
.flow-svg{display:block; height:auto; min-width:760px; max-width:none}
.flowview figcaption{margin-top:12px; color:var(--muted); font-size:13.5px; line-height:1.55;
  max-width:78ch}

/* The diagram draws itself: boxes land, then the arrows connect them.
   Opacity only - mermaid positions every node with a transform ATTRIBUTE, and
   a CSS transform overrides it, which yanks the whole graph to the origin.
   Graphviz nodes carry no such attribute, which is why the topology above can
   safely scale and these cannot. */
.flowview.live .node{ opacity:0; animation:flowNode .45s ease-out forwards;
  animation-delay:calc(var(--i) * 60ms); }
.flowview.live path.flowchart-link{ stroke-dasharray:1400; stroke-dashoffset:1400;
  animation:flowEdge 1.1s ease-out forwards; animation-delay:calc(700ms + var(--i) * 45ms); }
@keyframes flowNode{ from{opacity:0} to{opacity:1} }
@keyframes flowEdge{ to{stroke-dashoffset:0} }

@media (prefers-reduced-motion:reduce){
  .flowview.live .node{opacity:1; animation:none}
  .flowview.live path.flowchart-link{stroke-dasharray:none; stroke-dashoffset:0; animation:none}
  .flowview{transition:none}
}


/* ---------- the fabric deck ---------- */
/* A slide per fabric-view. The rail is one row wide per slide and moves by
   whole slides, so nothing is ever half on screen. */
.deck{padding:14px 0 6px}
.deck-head{display:flex; align-items:flex-end; justify-content:space-between; gap:24px}
.deck-nav{display:flex; gap:8px; padding-bottom:26px; flex:none}
.deck-arrow{width:38px; height:38px; border-radius:50%; border:1px solid var(--line);
  background:var(--surface); color:var(--muted); font-size:15px; line-height:1; cursor:pointer;
  transition:border-color .15s, color .15s, background .15s}
.deck-arrow:hover{border-color:var(--brand); color:var(--brand); background:var(--brand-wash)}

.deck-frame{overflow:hidden; border:1px solid var(--line); border-radius:var(--radius);
  background:var(--surface); box-shadow:var(--shadow)}
.deck-rail{display:flex; margin:0; padding:0; list-style:none;
  transition:transform .65s cubic-bezier(.4,.02,.2,1)}
.slide{flex:0 0 100%; min-width:100%; padding:20px 22px 18px;
  display:flex; flex-direction:column; gap:14px}

.slide-head{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.slide-fab{font-family:var(--display); font-weight:800; font-size:15px; letter-spacing:-.02em;
  color:#fff; background:var(--brand); border-radius:6px; padding:3px 9px}
.slide-title{font-weight:600; font-size:14.5px}
.slide-file{margin-left:auto; font-family:'JetBrains Mono',monospace; font-size:11.5px;
  color:var(--dim)}
.slide-art{min-height:210px; display:flex; align-items:center; justify-content:center}
.slide-svg{display:block; width:100%; height:auto; max-height:320px}
.slide-foot{display:flex; flex-wrap:wrap; gap:4px 16px; align-items:baseline;
  padding-top:12px; border-top:1px solid var(--line-soft)}
.slide-foot b{font-size:13.5px; font-weight:600}
.slide-foot span{font-size:13px; color:var(--muted)}

/* Each slide redraws as it arrives, so the fabric builds rather than slides in flat. */
.slide.live .node{ opacity:0; animation:nodeIn .45s cubic-bezier(.2,.7,.3,1) forwards;
  animation-delay:calc(300ms + var(--i) * 45ms); }
.slide.live .edge path{ stroke-dasharray:620; stroke-dashoffset:620;
  animation:edgeDraw .9s ease-out forwards; animation-delay:calc(650ms + var(--i) * 20ms); }

.deck-dots{display:flex; gap:7px; justify-content:center; padding-top:14px}
.deck-dots button{width:26px; height:4px; padding:0; border:none; border-radius:99px;
  background:#dce2ed; cursor:pointer; transition:background .3s, width .3s}
.deck-dots button.on{background:var(--brand); width:34px}
.deck-dots button:hover{background:#b9c5da}
.deck-dots button.on:hover{background:var(--brand)}

@media (max-width:700px){
  .deck-head{flex-direction:column; align-items:stretch}
  .deck-nav{padding-bottom:0; justify-content:flex-end}
  .slide-file{margin-left:0; width:100%}
}
@media (prefers-reduced-motion:reduce){
  .deck-rail{transition:none}
  .slide.live .node{opacity:1; animation:none}
  .slide.live .edge path{stroke-dasharray:none; stroke-dashoffset:0; animation:none}
}


/* Generated device configs, named so it is obvious they exist. */
.cfggrid{display:flex; flex-wrap:wrap; gap:6px; margin-bottom:14px}
.cfgchip{font-family:'JetBrains Mono',monospace; font-size:11.5px; color:var(--muted);
  background:var(--surface-2); border:1px solid var(--line); border-radius:5px; padding:4px 9px}

/* The outputs row reads as the mirror of the inputs row, so its markers are
   labels rather than the 01-04 sequence: these are not steps in an order. */
.outs .way-n{color:var(--teal); letter-spacing:.1em}


/* Sample fabric picker: three scenarios, one pipeline. */
.samplepick{display:grid; grid-template-columns:repeat(auto-fit,minmax(196px,1fr)); gap:10px;
  margin:0 0 18px}
.samp{display:flex; flex-direction:column; gap:3px; padding:13px 15px; cursor:pointer;
  border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--surface);
  transition:border-color .15s, background .15s}
.samp:hover{border-color:#cfd9ea}
.samp.on{border-color:var(--brand); background:var(--brand-wash)}
.samp input{position:absolute; opacity:0; width:0; height:0}
.samp b{font-size:14px; font-weight:700; letter-spacing:-.01em}
.samp.on b{color:var(--brand-ink)}
.samp span{font-size:12.5px; color:var(--muted)}

/* ---------- film: the two stock clips ----------------------------------
   Both are decoration. Neither carries information the page does not also
   state in text, so both are aria-hidden, neither has controls, and the
   poster frame is the whole experience for anyone whose browser declines to
   play them. The copy sits on a veil rather than straight on the footage, so
   contrast is a fixed value instead of whatever frame happens to be showing. */
.herofilm{position:relative; isolation:isolate; overflow:hidden; background:#050b16;
  display:flex; align-items:center;
  padding:clamp(60px,8vw,104px) 20px clamp(66px,9vw,112px)}
.herofilm-vid{position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  z-index:-2; pointer-events:none}
.herofilm-veil{position:absolute; inset:0; z-index:-1; background:
  linear-gradient(100deg, rgba(5,11,22,.95) 0%, rgba(5,11,22,.88) 38%,
                          rgba(5,11,22,.62) 72%, rgba(5,11,22,.5) 100%);}
.herofilm-inner{width:100%; max-width:1180px; margin:0 auto; padding:0 20px}
.herofilm .hero-copy{max-width:41rem}
/* Light-on-dark, by overriding the tokens the hero's own rules already read. */
.herofilm .hero-copy .eyebrow{background:rgba(255,255,255,.1);
  border-color:rgba(255,255,255,.22); color:#dbe6fe; backdrop-filter:blur(4px)}
.herofilm .hero-copy h1{color:#fff; max-width:19ch}
.herofilm .hero-copy h1 span{color:#93b4fd}
.herofilm .hero-copy p{color:#c3cfe2}
.btn.ghost.on-film{background:rgba(255,255,255,.08); border-color:rgba(255,255,255,.3);
  color:#fff; backdrop-filter:blur(4px)}
.btn.ghost.on-film:hover{background:rgba(255,255,255,.16); border-color:rgba(255,255,255,.45)}

.filmband{position:relative; isolation:isolate; overflow:hidden; background:#050b16;
  border-radius:var(--radius); min-height:284px; display:flex; align-items:flex-end;
  padding:clamp(28px,4vw,44px)}
.filmband-vid{position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  z-index:-2; pointer-events:none}
.filmband-veil{position:absolute; inset:0; z-index:-1; background:
  linear-gradient(20deg, rgba(5,11,22,.94) 6%, rgba(5,11,22,.72) 52%, rgba(5,11,22,.42) 100%);}
.filmband-copy{max-width:46rem}
.filmband-copy h2{font-family:var(--display); font-size:clamp(22px,2.6vw,31px); font-weight:800;
  letter-spacing:-.03em; line-height:1.15; margin:0 0 10px; color:#fff; text-wrap:balance}
.filmband-copy p{margin:0; color:#c3cfe2; font-size:15px; line-height:1.6}

.herofilm > .film-credit, .filmband > .film-credit{position:absolute; right:14px;
  bottom:10px; margin:0; z-index:1; max-width:none;
  font-size:11px; line-height:1.4; letter-spacing:.02em; color:rgba(255,255,255,.55)}
.film-credit a{color:rgba(255,255,255,.78)}

/* The diagrams now own the full column instead of half of it. */
.herostage{grid-template-columns:1fr; padding:30px 0 4px}
.herostage .hero-shot{max-width:940px; margin-inline:auto; width:100%}

/* Motion is never the only signal here, so reduced motion simply stops it and
   leaves the poster frame - which is the same picture, held still. */
/* Nothing is hidden here: a paused <video> renders its own poster, so reduced
   motion gets the identical picture, held still. The play() call is guarded in
   JS as well, so the footage never starts and then stops. */
@media (prefers-reduced-motion: reduce){
  .herofilm-vid, .filmband-vid{animation:none}
}
@media (max-width:620px){
  .filmband{min-height:230px}
  .film-credit{right:10px; bottom:6px; font-size:10px}
}

