:root {
  /* ---- Enterprise Steel ----------------------------------------------------
     Dark navy-slate base with a cool steel accent and brass used sparingly for
     primary actions. Chosen to read as infrastructure documentation to MNC and
     government buyers, while staying in the dark-console idiom homelab and SME
     visitors already work in. Every pairing below is WCAG AA or better.        */

  /* Structure */
  --ink: #101a2b;          /* page dark / text on light  L .007            */
  --ink-soft: #18253c;     /* raised panel                                  */
  --paper: #eef3f9;        /* light document surface     L .93             */
  --cream: #e6ecf5;        /* primary text on dark       15.3:1 on --ink    */

  /* Accents — derived from nexussec.org so the two brands read as one
     family. --ink and --paper are the parent's --text and --bg verbatim;
     the accent keeps the parent's --brand hue (221deg) but is lightened,
     because #2563eb sits at 2.3:1 on this dark base and is unreadable. */
  --lime: #7ea3f3;         /* PRIMARY steel accent       8.2:1 on --ink     */
  --green: #c9a227;        /* SPARING brass highlight     7.6:1 on --ink    */
  --steel: #7ea3f3;
  --steel-dim: #5182ef;
  --brass: #c9a227;
  --brass-bright: #e0b93f;
  --info: #0ea5b7;        /* parent --brand-2, verbatim   5.9:1 on --ink */
  --info-ink: #0a7683;    /* the same teal, for light surfaces           */

  /* Functional status colours — these keep their meaning from the hardware:
     green = tested/healthy, amber = needs attention / on request.            */
  --status-ok: #35d07f;
  --status-warn: #f5a524;

  /* Text tiers on dark */
  --text-2: #a9b7c6;
  --text-3: #7a8899;

  --line: rgba(16, 26, 43, 0.17);
  --muted: #5f7791;
  --mono: "DM Mono", monospace;
  --sans: "Manrope", sans-serif;
  --shadow: 0 16px 45px rgba(5, 9, 16, 0.18);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; color: var(--ink); background: var(--paper); font-family: var(--sans); overflow-x: hidden; }
button, input, select { font: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
a { color: inherit; text-decoration: none; }
button { cursor: pointer; }
.page-noise { pointer-events: none; position: fixed; inset: 0; z-index: 40; opacity: .045; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.6'/%3E%3C/svg%3E"); }
.announcement-bar { height: 38px; display: flex; align-items: center; justify-content: space-between; padding: 0 clamp(24px, 5vw, 76px); background: var(--lime); font-size: 10px; font-family: var(--mono); text-transform: uppercase; letter-spacing: .06em; }
.announcement-bar p { margin: 0; display: flex; align-items: center; gap: 9px; }
.announcement-bar a { text-decoration: underline; text-underline-offset: 3px; }
.pulse-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ink); animation: pulse 2.2s infinite; }
.site-header { height: 82px; display: flex; align-items: center; justify-content: space-between; padding: 0 clamp(24px, 5vw, 76px); border-bottom: 1px solid var(--line); position: absolute; top: 38px; left: 0; right: 0; z-index: 10; color: var(--cream); }
.brand { display: inline-flex; align-items: center; gap: 8px; font-weight: 800; letter-spacing: -.065em; font-size: 21px; line-height: 1; }
.brand > span:last-of-type > span { color: var(--lime); }
.brand b { font: 9px var(--mono); letter-spacing: .12em; align-self: flex-end; padding-bottom: 1px; color: var(--cream); }
.brand-mark { width: 28px; height: 28px; display: inline-flex; gap: 2px; align-items: center; transform: skewY(-24deg); }
.brand-mark i { display: block; width: 7px; height: 18px; background: var(--cream); }
.brand-mark i:nth-child(2) { height: 26px; background: var(--lime); }.brand-mark i:nth-child(3) { height: 12px; }
.desktop-nav { margin-left: auto; margin-right: 57px; display: flex; gap: 33px; font: 11px var(--mono); text-transform: uppercase; letter-spacing: .08em; }.desktop-nav a { opacity: .83; transition: opacity .2s; }.desktop-nav a:hover { opacity: 1; color: var(--lime); }
.header-actions { display: flex; align-items: center; gap: 4px; }.icon-button, .cart-trigger, .menu-trigger { border: 0; color: inherit; background: transparent; height: 38px; display: grid; place-items: center; }.icon-button { width: 38px; }.icon-button svg, .cart-trigger svg { width: 19px; fill: none; stroke: currentColor; stroke-width: 1.7; }.cart-trigger { width: 46px; position: relative; }.cart-count { position: absolute; top: 4px; right: 1px; min-width: 15px; height: 15px; padding: 0 3px; color: var(--ink); background: var(--lime); border-radius: 20px; display: grid; place-items: center; font: 9px var(--mono); }.menu-trigger { display: none; width: 38px; gap: 5px; align-content: center; }.menu-trigger span { display: block; width: 20px; height: 1px; background: currentColor; }
.mobile-nav { display:none; }
.hero { position: relative; min-height: 760px; background: var(--ink); color: var(--cream); overflow: hidden; display: grid; grid-template-columns: minmax(0, 1fr) minmax(440px, .9fr); padding: 190px clamp(24px, 8vw, 132px) 89px; }.hero-grid { position: absolute; inset: 0; opacity: .36; background-image: linear-gradient(rgba(246, 248, 250, .065) 1px, transparent 1px), linear-gradient(90deg, rgba(246, 248, 250, .065) 1px, transparent 1px); background-size: 77px 77px; mask-image: linear-gradient(to right, black 5%, transparent 66%); }.hero-grid:after { content: ""; position: absolute; width: 850px; height: 850px; left: -350px; top: 120px; border-radius: 50%; border: 1px solid rgba(127, 178, 217, .18); box-shadow: 0 0 0 120px rgba(127, 178, 217, .025), 0 0 0 240px rgba(127, 178, 217, .018); }
.hero-content { position: relative; z-index: 1; max-width: 655px; }.eyebrow { margin: 0 0 20px; display: flex; align-items: center; gap: 10px; color: #7e98b9; text-transform: uppercase; font: 10px var(--mono); letter-spacing: .07em; }.eyebrow span { color: var(--green); }.eyebrow.light { color: #95a5bb; }.eyebrow.light span { color: var(--lime); }
h1, h2, h3, p { margin-top: 0; } h1, h2 { font-weight: 600; letter-spacing: -.065em; line-height: .96; } h1 { font-size: clamp(60px, 6.3vw, 104px); margin-bottom: 28px; } h1 em, h2 em { color: var(--lime); font-style: normal; }.hero-copy { max-width: 490px; color: #adb9c8; font-size: 15px; line-height: 1.8; margin-bottom: 35px; }
.hero-actions { display: flex; align-items: center; gap: 27px; }.button { border: 1px solid transparent; display: inline-flex; align-items: center; justify-content: center; gap: 20px; min-height: 52px; padding: 0 19px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .075em; transition: transform .2s, background .2s, border-color .2s; }.button:hover { transform: translateY(-2px); }.button-primary { background: var(--lime); color: var(--ink); }.button-primary:hover { background: #a9cbe6; }.button span { font-size: 19px; font-weight: 400; line-height: 0; }.button-text { background: transparent; color: var(--cream); padding: 0; min-height: auto; border: 0; }.play-icon { display: grid; place-items: center; width: 23px; height: 23px; border: 1px solid rgba(230, 236, 245, .5); border-radius: 50%; font-size: 7px !important; }.hero-footnotes { display: flex; gap: 42px; margin-top: 76px; }.hero-footnotes > div { display: flex; gap: 10px; align-items: flex-start; }.hero-footnotes strong { font-size: 18px; letter-spacing: -.06em; color: var(--lime); }.hero-footnotes span { font: 9px/1.5 var(--mono); color: #7f94b0; text-transform: uppercase; letter-spacing: .03em; }
.hero-visual { position: relative; min-height: 500px; align-self: center; isolation: isolate; }.orbit { position: absolute; border: 1px solid rgba(127, 178, 217, .27); width: 550px; height: 310px; border-radius: 50%; left: 5%; top: 85px; transform: rotate(-45deg); }.orbit-two { width: 790px; height: 440px; top: 25px; left: -90px; border-color: rgba(230, 236, 245, .13); }.scan-line { position: absolute; width: 430px; top: 243px; left: 52%; height: 1px; transform: translateX(-50%) rotate(-18deg); background: var(--lime); box-shadow: 0 0 20px 3px rgba(127, 178, 217, .5); }.rack-shadow { position: absolute; width: 290px; height: 70px; bottom: 5px; left: 51%; transform: translateX(-50%); filter: blur(20px); background: rgba(0, 0, 0, .86); border-radius: 50%; }.server-rack { width: 273px; height: 454px; border: 6px solid #2e425b; border-top-width: 13px; background: #121b27; position: absolute; bottom: 22px; left: 50%; transform: translateX(-50%) skewY(-5deg); box-shadow: -35px 36px 22px rgba(0,0,0,.45), 20px 10px 0 #070b10; z-index: 1; padding: 31px 9px 9px; }.server-rack:before, .server-rack:after { content: ""; position: absolute; top: -13px; bottom: -6px; width: 8px; background: #5c799e; }.server-rack:before { left: -6px; }.server-rack:after { right: -6px; }.rack-brand { position: absolute; top: 7px; left: 13px; font: 7px var(--mono); color: #93a4b9; letter-spacing: .08em; }.status-dot { width: 5px; height: 5px; display: inline-block; border-radius: 50%; background: var(--lime); box-shadow: 0 0 6px var(--lime); margin-right: 3px; }.rack-unit { height: 57px; background: linear-gradient(90deg,#283950,#141e2b 10%,#131d29 90%,#2f425b); border-top: 2px solid #415978; border-bottom: 1px solid #04070a; display: flex; gap: 4px; padding: 17px 19px; position: relative; }.rack-unit:nth-child(odd) { background: linear-gradient(90deg,#3c5371,#172230 10%,#172231 90%,#4a6486); }.rack-unit span { width: 5px; height: 5px; border-radius: 50%; background: var(--lime); box-shadow: 0 0 4px rgba(127, 178, 217, .8); }.rack-unit span:nth-child(2) { background:#63a4d3; }.rack-unit b { position: absolute; right: 12px; color:#647fa3; font: 8px var(--mono); }.rack-base { height: 15px; background: #2a3c54; margin: 7px 24px 0; }.signal-card { position: absolute; z-index: 3; background: rgba(22, 32, 46, .88); border: 1px solid rgba(127, 178, 217, .55); padding: 12px 15px; width: 133px; backdrop-filter: blur(5px); }.signal-card span { display:block; color:#8599b3; font:7px var(--mono); letter-spacing:.07em; }.signal-card strong { display:block; color:var(--cream); font:12px var(--mono); margin-top:6px; }.signal-card i { display:block; height:2px; margin-top:9px; background: linear-gradient(90deg,var(--lime) 63%, rgba(127, 178, 217, .15) 63%); }.card-top { right: 8%; top: 80px; }.card-bottom { left: 3%; bottom: 82px; }.card-bottom i { background:linear-gradient(90deg,var(--lime) 90%, rgba(127, 178, 217, .15) 90%); }.visual-index { position:absolute; right: 0; bottom: 5px; font: 8px/1.6 var(--mono); color: #7990ad; letter-spacing:.09em; }.scroll-indicator { position: absolute; bottom: 28px; left: clamp(24px, 8vw, 132px); display: flex; align-items:center; gap:9px; color:#879ab3; font: 9px var(--mono); text-transform:uppercase; letter-spacing:.08em; }.scroll-indicator span { display:block; height:29px; width:1px; background:var(--lime); }
.marquee { height: 71px; display: flex; align-items: center; overflow: hidden; background: var(--lime); border-bottom: 1px solid var(--ink); }.marquee-track { white-space: nowrap; display:flex; align-items:center; animation: marquee 27s linear infinite; }.marquee-track span { display:inline-flex; align-items:center; gap:29px; margin-right:29px; font-size:12px; font-weight:800; letter-spacing:.02em; }.marquee-track b { font-size:14px; }
.section-shell { padding-left: clamp(24px, 8vw, 132px); padding-right: clamp(24px, 8vw, 132px); }.category-section { padding-top: 133px; padding-bottom: 137px; }.section-heading { display:flex; justify-content:space-between; gap:48px; align-items:flex-end; }.section-heading > div { max-width:620px; }.section-heading h2 { font-size: clamp(43px, 5vw, 75px); margin:0; }.section-heading > p { max-width:320px; color:#8097b6; font-size:13px; line-height:1.8; margin: 0 0 7px; }
.category-grid { display:grid; grid-template-columns:repeat(6,1fr); margin-top:65px; border-top:1px solid var(--line); border-left:1px solid var(--line); }.category-card { min-height:256px; border-right:1px solid var(--line); border-bottom:1px solid var(--line); padding:19px; position:relative; overflow:hidden; transition: background .25s, color .25s; }.category-card:first-child,.category-card:nth-child(2) { grid-column:span 3; }.category-card:nth-child(n+3) { grid-column:span 2; }.category-card:hover { background:var(--ink); color:var(--cream); }.card-index { position:absolute; top:19px; right:20px; font:9px var(--mono); color:#7d92ae; }.category-icon { display:flex; align-items:center; gap:3px; height:84px; margin:15px 0 32px; }.category-icon i { display:block; background:var(--ink); transition:background .25s; }.category-card:hover .category-icon i { background:var(--lime); }.icon-server { width:150px; height:82px; padding: 13px 12px; border:4px solid var(--ink); transition:border-color .25s; }.category-card:hover .icon-server { border-color:var(--lime); }.icon-server i { height:7px; flex:1; }.icon-server i:nth-child(2) { flex:7; }.icon-firewall { gap:5px; }.icon-firewall:before { content:""; display:block; width:90px; height:42px; border:4px solid var(--ink); border-right:0; transition:border-color .25s; }.category-card:hover .icon-firewall:before { border-color:var(--lime); }.icon-firewall i { width:6px; height:6px; }.icon-switch { width:144px; height:50px; padding:15px 10px; gap:6px; border:4px solid var(--ink); transition:border-color .25s; }.category-card:hover .icon-switch { border-color:var(--lime); }.icon-switch i { width:7px; height:7px; }.icon-ap { width:70px; height:70px; border:3px solid var(--ink); border-radius:50%; justify-content:center; transition:border-color .25s; }.icon-ap:before,.icon-ap:after { content:""; position:absolute; border:1px solid var(--ink); border-radius:50%; transition:border-color .25s; }.icon-ap:before { width:102px;height:102px; }.icon-ap:after { width:132px;height:132px; }.category-card:hover .icon-ap,.category-card:hover .icon-ap:before,.category-card:hover .icon-ap:after { border-color:var(--lime); }.icon-ap i { width:8px; height:8px; border-radius:50%; }.icon-storage { border:4px solid var(--ink); width:102px; height:69px; padding:17px 9px; gap:4px; transition:border-color .25s; }.category-card:hover .icon-storage {border-color:var(--lime)}.icon-storage i { flex:1;height:26px;}.category-card h3 { margin:0 0 8px;font-size:17px;letter-spacing:-.045em; }.category-card p { margin:0; font-size:11px;color:#8298b4; }.category-card:hover p { color:#95a6bb; }.circle-arrow { position:absolute;right:20px;bottom:19px;width:28px;height:28px;border:1px solid var(--line);border-radius:50%;display:grid;place-items:center;font-size:15px;transition:border-color .25s;}.category-card:hover .circle-arrow {border-color:rgba(127, 178, 217, .6);color:var(--lime)}
.inventory-section { background:var(--ink); color:var(--cream); padding:120px 0 113px; }.inventory-heading { align-items:flex-end; }.button-outline { color:var(--cream); border-color:rgba(230, 236, 245, .34); background:transparent; }.button-outline:hover { border-color:var(--lime); color:var(--lime); }.inventory-toolbar { border-top:1px solid rgba(230, 236, 245, .18); border-bottom:1px solid rgba(230, 236, 245, .18); min-height:88px; display:flex; align-items:center; justify-content:space-between; margin-top:59px; gap:18px; }.filter-pills { display:flex; align-items:center; flex-wrap:wrap; gap:5px; }.filter-pill { color:#94a5ba; border:0; background:transparent; padding:8px 11px; font:10px var(--mono); text-transform:uppercase; letter-spacing:.03em; }.filter-pill.active,.filter-pill:hover { background:var(--lime); color:var(--ink); }.text-button { color:#c8cfd8;background:transparent;border:0;font:10px var(--mono);text-transform:uppercase;letter-spacing:.04em; }.text-button span { color:var(--lime); margin-left:8px; }.product-grid { display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:rgba(230, 236, 245, .18);border:1px solid rgba(230, 236, 245, .18);margin-top:28px; }.product-card { background:#121a26; min-height:486px; padding:19px 19px 17px; position:relative; display:flex;flex-direction:column; overflow:hidden; transition:opacity .25s, transform .25s; }.product-card.hidden { display:none; }.product-topline { display:flex; justify-content:space-between; color:#7f94af; font:9px var(--mono); letter-spacing:.05em; }.in-stock { color:#d8c078; }.product-image { height:188px; margin:14px 0 10px; display:grid;place-items:center;position:relative;background:radial-gradient(circle at 50% 55%,rgba(127, 178, 217, .1),transparent 60%); }.product-image:after { content:"";position:absolute;width:74%;height:13px;bottom:8px;border-radius:50%;background:rgba(0,0,0,.62);filter:blur(7px); }.rack-product { position:relative;z-index:1;width:218px;height:117px;background:linear-gradient(#3a506d,#182332 8%,#1a2636 91%,#3b516f);border:5px solid #577297;padding:20px 19px;display:flex;gap:7px;box-shadow: 18px 16px 17px rgba(0,0,0,.5); }.rack-product:after { content:"";position:absolute;inset:12px 9px;border-top:2px solid #334762;border-bottom:2px solid #334762; }.rack-product i { width:6px;height:6px;position:relative;z-index:1;border-radius:50%;background:var(--lime);box-shadow:0 0 5px var(--lime);}.rack-product i:nth-child(2),.rack-product i:nth-child(5){background:#5b9fd0;box-shadow:0 0 5px #5b9fd0}.rack-product b { position:absolute;z-index:1;right:22px;top:30px;width:86px;height:35px;background:repeating-linear-gradient(to bottom,#0f1620 0 2px,transparent 2px 6px); }.firewall-product { position:relative;z-index:1;width:260px;height:64px;border:5px solid #557094;background:linear-gradient(#415878,#131c29 18%,#1b2839);padding:21px 16px;display:flex;gap:8px;box-shadow:17px 14px 15px rgba(0,0,0,.5); }.firewall-product:after {content:"";position:absolute;bottom:-11px;left:27px;width:5px;height:10px;background:#4a6486;box-shadow:193px 0 #4a6486}.firewall-product i {width:7px;height:7px;background:#93c5e4;border-radius:50%;}.firewall-product i:nth-child(2n){background:var(--lime);}.firewall-product b {margin-left:auto;width:57px;height:10px;border:1px solid #5a769b;background:repeating-linear-gradient(90deg,#546f93 0 2px,transparent 2px 5px)}.switch-product {position:relative;z-index:1;width:270px;height:75px;padding:25px 15px;background:linear-gradient(#425a7a,#141d2a 16%,#182433);border:5px solid #567196;display:flex;gap:5px;box-shadow:17px 14px 15px rgba(0,0,0,.5)}.switch-product i{width:10px;height:9px;border:1px solid #7d92af;background:#0a0f16}.switch-product i:nth-child(4n){background:#86bde0}.switch-product b{position:absolute;right:17px;bottom:10px;width:9px;height:4px;background:var(--lime)}.ap-product {position:relative;z-index:2;width:110px;height:110px;border-radius:50%;border:9px solid #c5ccd6;background:radial-gradient(circle at 43% 38%,#f2f6fa,#627ea2);box-shadow:12px 16px 18px rgba(0,0,0,.45)}.ap-product i{position:absolute;top:31px;width:5px;height:5px;border-radius:50%;background:#5c789d}.ap-product i:nth-child(1){left:31px}.ap-product i:nth-child(2){left:43px;background:var(--green)}.ap-product i:nth-child(3){left:55px}.ap-product b{position:absolute;left:37px;bottom:25px;width:19px;height:2px;background:#6580a3}.wireless-ring {position:absolute;z-index:1;border:1px solid rgba(127, 178, 217, .3);border-radius:50%;}.ring-a{width:150px;height:150px}.ring-b{width:208px;height:208px}.drive-product{position:relative;z-index:1;width:150px;height:159px;border-radius:8px;background:linear-gradient(120deg,#d2d8df,#4e688a);border:6px solid #a2b0c1;box-shadow:14px 15px 15px rgba(0,0,0,.4)}.drive-product:before{content:"";position:absolute;left:22px;top:19px;width:91px;height:91px;border:3px solid #324761;border-radius:50%;background:radial-gradient(circle,#9baabe 0 5px,#455d7e 6px 27px,#94a4ba 28px 32px,#293b52 33px 34px,#a8b4c5 35px)}.drive-product i{position:absolute;right:22px;top:32px;width:17px;height:9px;background:#6f88a8}.drive-product i:nth-child(2){top:118px;right:30px;width:8px;height:8px;border-radius:50%;background:var(--green)}.drive-product b{position:absolute;left:15px;bottom:12px;width:46px;height:8px;background:#3e5573}.drive-product em{position:absolute;right:16px;bottom:12px;width:22px;height:8px;background:#3e5573}.product-details { flex:1; }.product-details p { color:var(--lime);font:9px var(--mono);letter-spacing:.05em;text-transform:uppercase;margin:0 0 7px;}.product-details h3{font-size:18px;letter-spacing:-.055em;margin:0 0 15px}.product-details ul{list-style:none;margin:0;padding:0;display:grid;gap:5px;color:#94a5ba;font-size:10px}.product-details li:before{content:"/";color:var(--lime);margin-right:7px}.product-bottom{display:flex;justify-content:space-between;align-items:flex-end;margin-top:16px}.product-bottom strong{font:9px var(--mono);font-weight:400;color:#8ea0b7}.product-bottom strong span{display:block;color:var(--cream);font:15px var(--sans);font-weight:700;letter-spacing:-.04em;margin-top:3px}.add-button{border:1px solid rgba(230, 236, 245, .33);background:transparent;color:var(--cream);width:36px;height:36px;font-size:21px;font-weight:300;transition:.2s}.add-button:hover{color:var(--ink);background:var(--lime);border-color:var(--lime)}.product-card-cta{background:var(--lime);padding:28px;justify-content:flex-end;isolation:isolate}.product-card-cta .eyebrow{color:#5a4a14}.product-card-cta .eyebrow span{color:var(--ink)}.product-card-cta h3{color:var(--ink);font-size:29px;line-height:1.06;letter-spacing:-.065em;position:relative;z-index:1;max-width:330px}.product-card-cta .button{align-self:flex-start;position:relative;z-index:1;background:var(--ink);color:var(--lime);margin-top:8px}.cta-grid{position:absolute;inset:0;opacity:.2;background-image:linear-gradient(var(--ink) 1px,transparent 1px),linear-gradient(90deg,var(--ink) 1px,transparent 1px);background-size:38px 38px;mask-image:linear-gradient(135deg,transparent 18%,#000 75%)}.inventory-note{margin:20px 0 0;text-align:center;color:#7e93af;font-size:10px}.inventory-note button{color:var(--lime);background:transparent;border:0;text-decoration:underline;text-underline-offset:3px;padding:0;font-size:10px}.assurance-section{padding-top:130px;padding-bottom:140px}.assurance-intro{display:grid;grid-template-columns:1.15fr 1fr;column-gap:50px}.assurance-intro .eyebrow{grid-column:1}.assurance-intro h2{font-size:clamp(43px,5vw,75px);margin:0;grid-column:1}.assurance-intro>p:last-child{align-self:end;margin:0 0 5px;max-width:360px;color:#8097b6;font-size:13px;line-height:1.8}.assurance-process{display:grid;grid-template-columns:repeat(4,1fr);margin-top:80px;border-top:1px solid var(--line);border-left:1px solid var(--line)}.assurance-process article{border-right:1px solid var(--line);border-bottom:1px solid var(--line);padding:20px 20px 30px;min-height:278px}.assurance-process article>span{font:9px var(--mono);color:#8197b5}.process-icon{height:92px;position:relative;display:flex;align-items:center}.process-icon i{display:block;background:var(--ink)}.inspect-icon:before{content:"";width:62px;height:62px;border:4px solid var(--ink);border-radius:50%}.inspect-icon:after{content:"";position:absolute;width:36px;height:4px;background:var(--green);transform:rotate(-45deg);left:58px;top:61px}.inspect-icon i{position:absolute;width:7px;height:7px;border-radius:50%;left:29px;top:41px}.inspect-icon i:nth-child(2){left:44px;top:55px;background:var(--green)}.wipe-icon{gap:8px}.wipe-icon:before{content:"";width:75px;height:55px;border:4px solid var(--ink);border-top:0}.wipe-icon:after{content:"";position:absolute;left:21px;top:19px;width:33px;height:50px;border-left:4px solid var(--green);border-bottom:4px solid var(--green);transform:rotate(-45deg)}.wipe-icon i{width:7px;height:7px;border-radius:50%}.tune-icon:before,.tune-icon:after{content:"";position:absolute;background:var(--ink)}.tune-icon:before{width:89px;height:4px;top:29px;box-shadow:0 29px var(--ink)}.tune-icon:after{width:4px;height:62px;left:24px}.tune-icon i{position:absolute;width:17px;height:17px;border:4px solid var(--ink);border-radius:50%;top:22px;left:17px;background:var(--paper)}.tune-icon i:nth-child(2){top:51px;left:57px}.tune-icon i:nth-child(3){top:22px;left:72px;border-color:var(--green)}.ship-icon:before{content:"";width:76px;height:50px;border:4px solid var(--ink);border-right:0}.ship-icon:after{content:"";position:absolute;left:35px;top:25px;width:27px;height:27px;border:4px solid var(--green);border-top:0;border-left:0;transform:rotate(-45deg)}.ship-icon i{position:absolute;width:12px;height:12px;background:var(--ink);border-radius:50%;top:68px;left:15px}.ship-icon i:nth-child(2){left:61px}.assurance-process h3{font-size:16px;letter-spacing:-.045em;margin:0 0 10px}.assurance-process p{margin:0;color:#8298b5;font-size:11px;line-height:1.7}.assurance-stats{display:grid;grid-template-columns:repeat(4,1fr);margin-top:38px}.assurance-stats div{display:flex;align-items:center;gap:11px}.assurance-stats strong{font-size:28px;letter-spacing:-.07em}.assurance-stats span{color:#8098b6;font:9px/1.45 var(--mono);text-transform:uppercase;letter-spacing:.03em}
.architect-section{padding:0 clamp(24px,5vw,76px) 72px;background:var(--paper)}.architect-panel{background:var(--ink);color:var(--cream);display:grid;grid-template-columns:1fr 1fr;min-height:567px;position:relative;overflow:hidden}.architect-panel:before{content:"";position:absolute;width:680px;height:680px;border:1px solid rgba(127, 178, 217, .2);border-radius:50%;left:-290px;bottom:-490px;box-shadow:0 0 0 75px rgba(127, 178, 217, .025),0 0 0 150px rgba(127, 178, 217, .018)}.architect-copy{padding:78px clamp(30px,6vw,101px);position:relative}.architect-copy h2{font-size:clamp(48px,5vw,75px);margin:0 0 28px}.architect-copy>p:not(.eyebrow){color:#a3b0c2;font-size:13px;line-height:1.8;max-width:340px}.architect-meta{margin-top:59px;display:flex;gap:24px;color:#a0aec1;font:9px var(--mono);text-transform:uppercase;letter-spacing:.02em}.architect-meta b{color:var(--lime);font-weight:400}.architecture-form{position:relative;background:#18253c;padding:62px clamp(28px,5vw,80px) 34px;display:flex;flex-direction:column}.form-step{display:flex;justify-content:space-between;margin-bottom:28px}.form-step span{color:var(--lime);font:9px var(--mono);letter-spacing:.07em}.form-step strong{font-size:13px;letter-spacing:-.04em}.field-label{color:#a2afc1;font:9px var(--mono);text-transform:uppercase;letter-spacing:.05em;margin-bottom:22px}.field-label select,.field-label input{display:block;width:100%;color:var(--cream);background:transparent;border:0;border-bottom:1px solid rgba(230, 236, 245, .32);outline:0;padding:12px 0 11px;font:13px var(--sans);appearance:none;border-radius:0}.field-label select{background-image:linear-gradient(45deg,transparent 50%,var(--lime) 50%),linear-gradient(135deg,var(--lime) 50%,transparent 50%);background-position:calc(100% - 11px) 17px,calc(100% - 6px) 17px;background-size:5px 5px,5px 5px;background-repeat:no-repeat}.field-label select option{background:var(--ink)}.field-label input::placeholder{color:#8097b6}.choice-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:11px}.choice-grid input{position:absolute;opacity:0}.choice-grid label{min-height:39px;display:grid;place-items:center;color:#a1afc1;border:1px solid rgba(230, 236, 245, .24);font:9px var(--mono);text-transform:none;letter-spacing:0}.choice-grid input:checked+label{border-color:var(--lime);color:var(--lime);background:rgba(127, 178, 217, .06)}.form-submit{width:100%;margin-top:3px}.form-privacy{color:#8297b4;font-size:9px;line-height:1.6;margin:15px 0 0;text-align:center}.site-footer{padding:51px clamp(24px,5vw,76px) 27px;background:#dde7f2}.footer-top{display:grid;grid-template-columns:1.2fr 1fr 1fr;align-items:start;min-height:157px}.footer-brand{color:var(--ink)}.footer-brand b{color:#7f98ba}.footer-brand .brand-mark i{background:var(--ink)}.footer-brand .brand-mark i:nth-child(2){background:var(--green)}.footer-top p{font-size:16px;letter-spacing:-.05em;line-height:1.25;margin:1px 0}.footer-contact{justify-self:end;font-size:14px;font-weight:700;letter-spacing:-.05em;text-decoration:underline;text-underline-offset:5px}.footer-contact span{color:var(--green);font-size:19px;margin-left:5px}.footer-bottom{border-top:1px solid rgba(16, 26, 43, .18);padding-top:18px;display:flex;justify-content:space-between;color:#8098b7;font:9px var(--mono);text-transform:uppercase;letter-spacing:.03em}.footer-bottom div{display:flex;gap:20px}.footer-bottom a:hover{color:var(--ink)}
.quote-drawer{position:fixed;z-index:60;right:0;top:0;bottom:0;width:min(100%,440px);background:var(--cream);color:var(--ink);transform:translateX(102%);transition:transform .35s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;padding:32px}.quote-drawer.open{transform:translateX(0)}.drawer-header{display:flex;justify-content:space-between;align-items:flex-start;border-bottom:1px solid var(--line);padding-bottom:25px}.drawer-header .eyebrow{margin-bottom:8px}.drawer-header h2{font-size:38px;margin:0}.drawer-close{border:0;background:transparent;font-size:34px;font-weight:300;line-height:.7}.quote-items{flex:1;overflow:auto;padding:18px 0}.empty-quote{margin-top:12px;color:#8197b5;font-size:12px;line-height:1.7}.quote-item{display:flex;justify-content:space-between;gap:20px;padding:15px 0;border-bottom:1px solid var(--line)}.quote-item p{margin:0;font:9px var(--mono);color:#647fa3;text-transform:uppercase}.quote-item strong{display:block;font-size:14px;letter-spacing:-.04em;margin-top:5px}.quote-remove{align-self:center;background:transparent;border:0;color:#8298b4;font:9px var(--mono);text-decoration:underline}.drawer-footer{border-top:1px solid var(--line);padding-top:18px}.drawer-footer p{color:#8097b6;font-size:11px;line-height:1.6;margin-bottom:15px}.drawer-footer .button{width:100%}.overlay{position:fixed;z-index:50;inset:0;background:rgba(5, 9, 16, .56);opacity:0;visibility:hidden;transition:.25s}.overlay.visible{opacity:1;visibility:visible}.search-modal{position:fixed;z-index:70;inset:0;display:grid;place-items:start center;padding-top:10vh;background:rgba(5, 9, 16, .72);opacity:0;visibility:hidden;transition:.2s}.search-modal.open{opacity:1;visibility:visible}.search-box{width:min(92vw,700px);background:var(--cream);box-shadow:var(--shadow);}.search-input-wrap{height:74px;display:flex;align-items:center;gap:14px;padding:0 18px;border-bottom:1px solid var(--line)}.search-input-wrap svg{width:19px;stroke:var(--ink);fill:none;stroke-width:1.7}.search-input-wrap input{border:0;outline:0;background:transparent;flex:1;font-size:16px}.search-close{color:#7f98b8;background:transparent;border:1px solid var(--line);font:9px var(--mono);padding:6px}.search-results{min-height:145px;padding:17px}.search-results p{font-size:12px;color:#8298b5;margin:0}.search-result{padding:13px 0;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;align-items:center}.search-result:last-child{border:0}.search-result p{font:9px var(--mono);color:#8098b6;text-transform:uppercase;margin:0 0 4px}.search-result strong{font-size:14px;letter-spacing:-.04em}.search-result button{background:var(--ink);color:var(--lime);border:0;padding:8px 10px;font:9px var(--mono);text-transform:uppercase}.toast{position:fixed;z-index:80;left:50%;bottom:25px;transform:translate(-50%,125px);background:var(--lime);color:var(--ink);padding:13px 18px;font:10px var(--mono);text-transform:uppercase;letter-spacing:.04em;box-shadow:var(--shadow);transition:transform .3s}.toast.show{transform:translate(-50%,0)}
.header-link { color:var(--cream); font:10px var(--mono); text-transform:uppercase; letter-spacing:.05em; }.header-link span { color:var(--lime); font-size:15px; margin-left:4px; }.desktop-nav a.active { color:var(--lime); opacity:1; }
.page-masthead { min-height:425px; padding:174px clamp(24px, 8vw, 132px) 68px; display:flex; flex-direction:column; justify-content:flex-end; position:relative; overflow:hidden; }.page-masthead-dark { background:var(--ink); color:var(--cream); }.page-masthead-dark:before { content:""; position:absolute; inset:0; opacity:.34; background-image:linear-gradient(rgba(246, 248, 250, .06) 1px,transparent 1px),linear-gradient(90deg,rgba(246, 248, 250, .06) 1px,transparent 1px); background-size:70px 70px; mask-image:linear-gradient(120deg,#000,transparent 80%); }.page-masthead-dark:after { content:""; position:absolute; width:580px; height:580px; border:1px solid rgba(127, 178, 217, .22); border-radius:50%; right:-135px; bottom:-430px; box-shadow:0 0 0 80px rgba(127, 178, 217, .025),0 0 0 160px rgba(127, 178, 217, .015); }.page-masthead > * { position:relative; z-index:1; }.page-masthead .eyebrow { margin-bottom:17px; }.page-masthead h1 { font-size:clamp(46px, 5.4vw, 80px); margin:0; }.page-masthead > p:last-child { max-width:430px; color:#a2afc1; font-size:13px; line-height:1.75; margin:22px 0 0; }
.home-routes { padding-top:0; padding-bottom:102px; display:grid; grid-template-columns:1fr 1fr; gap:1px; background:var(--paper); }.home-route { min-height:375px; padding:42px clamp(25px,4.2vw,67px); position:relative; overflow:hidden; display:flex; flex-direction:column; justify-content:flex-end; }.home-route h2 { position:relative; z-index:1; font-size:clamp(38px,4vw,62px); margin:0 0 33px; }.route-assurance { background:var(--ink); color:var(--cream); }.route-assurance .eyebrow { position:absolute; top:43px; left:clamp(25px,4.2vw,67px); }.route-orbit { width:300px; height:300px; position:absolute; right:-70px; top:-130px; border:1px solid rgba(127, 178, 217, .4); border-radius:50%; box-shadow:0 0 0 42px rgba(127, 178, 217, .04),0 0 0 84px rgba(127, 178, 217, .025); }.route-architect { background:var(--lime); color:var(--ink); }.route-architect .eyebrow { position:absolute; top:43px; left:clamp(25px,4.2vw,67px); color:#6b5a1e; }.route-architect .eyebrow span { color:var(--ink); }.route-grid { position:absolute; inset:0; opacity:.2; background-image:linear-gradient(var(--ink) 1px,transparent 1px),linear-gradient(90deg,var(--ink) 1px,transparent 1px); background-size:35px 35px; mask-image:linear-gradient(135deg,transparent 26%,#000 75%); }.route-action { position:relative; z-index:1; font:10px var(--mono); text-transform:uppercase; letter-spacing:.05em; }.route-action b { color:var(--lime); font-size:18px; margin-left:7px; }.route-architect .route-action b { color:var(--ink); }
.inventory-page-section { padding-top:0; }.inventory-page-section .inventory-toolbar { margin-top:0; }.assurance-cta { background:var(--ink); color:var(--cream); padding:75px clamp(24px,8vw,132px); display:flex; justify-content:space-between; align-items:flex-end; gap:30px; }.assurance-cta h2 { font-size:clamp(38px,4.5vw,65px); margin:0; }.architect-page-section { padding-top:0; padding-bottom:0; }.architect-page-section .architect-panel { margin:0 auto; max-width:1288px; }.architect-support { padding-top:109px; padding-bottom:115px; }.architect-support > div { display:flex; justify-content:space-between; gap:50px; align-items:flex-end; }.architect-support h2 { font-size:clamp(40px,4.5vw,67px); margin:0; }.architect-support p:last-child { max-width:360px; color:#8097b6; font-size:13px; line-height:1.8; margin:0 0 6px; }
@media (max-width:880px) { .header-link { display:none; }.home-routes { grid-template-columns:1fr; padding-bottom:0; }.page-masthead { min-height:375px; }.architect-page-section { padding-left:0; padding-right:0; }.assurance-cta { margin-top:0; }.architect-support > div { display:block; }.architect-support p:last-child { margin-top:22px; } }
@media (max-width:600px) { .page-masthead { min-height:344px; padding:147px 20px 45px; }.page-masthead h1 { font-size:49px; }.page-masthead > p:last-child { font-size:12px; margin-top:16px; }.home-routes { margin:0 -20px; }.home-route { min-height:310px; padding:30px 20px; }.route-assurance .eyebrow,.route-architect .eyebrow { top:31px; left:20px; }.home-route h2 { font-size:43px; margin-bottom:24px; }.assurance-cta { padding:54px 20px; display:block; }.assurance-cta .button { margin-top:26px; }.architect-support { padding-top:78px; padding-bottom:80px; }.architect-support h2 { font-size:46px; } }
.labs-scope { background:#111924; color:var(--cream); padding:72px clamp(24px,8vw,132px); display:grid; grid-template-columns:1.1fr .9fr; gap:60px; align-items:end; }.labs-scope h2 { font-size:clamp(38px,4vw,62px); margin:0; }.labs-scope>p { margin:0 0 6px; max-width:445px; color:#a9b5c5; font-size:14px; line-height:1.8; }.labs-scope a { color:var(--lime); text-decoration:underline; text-underline-offset:4px; }.inventory-note a { color:var(--lime); text-decoration:underline; text-underline-offset:3px; }
.about-intro { padding-top:122px; padding-bottom:82px; display:grid; grid-template-columns:1.1fr .8fr; gap:60px; align-items:end; }.about-intro h2 { font-size:clamp(44px,5vw,73px); margin:0; }.about-intro>p { color:#8097b6; font-size:14px; line-height:1.85; margin:0 0 7px; }.audience-grid { display:grid; grid-template-columns:repeat(4,1fr); padding-bottom:125px; }.audience-grid article { padding:22px 22px 28px; min-height:235px; border:1px solid var(--line); border-left:0; }.audience-grid article:first-child { border-left:1px solid var(--line); }.audience-grid span { color:var(--green); font:10px var(--mono); }.audience-grid h3 { font-size:18px; letter-spacing:-.05em; margin:65px 0 11px; }.audience-grid p { color:#8197b5; font-size:11px; line-height:1.75; margin:0; }.brand-section { background:var(--ink); color:var(--cream); padding:101px 0 98px; }.brand-section h2 { font-size:clamp(43px,5vw,72px); margin:0; }.brand-list { display:grid; grid-template-columns:repeat(4,1fr); border-top:1px solid rgba(230, 236, 245, .19); border-left:1px solid rgba(230, 236, 245, .19); margin-top:55px; }.brand-list span { padding:22px; min-height:78px; border-right:1px solid rgba(230, 236, 245, .19); border-bottom:1px solid rgba(230, 236, 245, .19); font-size:17px; font-weight:700; letter-spacing:-.05em; display:flex; align-items:center; }.brand-note { max-width:450px; color:#96a6bb; font-size:12px; line-height:1.8; margin:26px 0 0; }
.quote-notice { padding-top:58px; padding-bottom:58px; text-align:center; }.quote-notice p { margin:0 auto; max-width:700px; color:#8097b6; font-size:13px; line-height:1.8; }.quote-notice strong,.quote-notice a { color:var(--ink); }.quote-notice a { text-decoration:underline; text-underline-offset:3px; }.form-privacy a { color:var(--lime); text-decoration:underline; text-underline-offset:3px; }
.legal-layout { display:grid; grid-template-columns:220px minmax(0,750px); justify-content:center; gap:90px; padding-top:86px; padding-bottom:120px; }.legal-nav { align-self:start; position:sticky; top:24px; display:flex; flex-direction:column; gap:2px; padding-top:6px; }.legal-nav>span { color:#8198b6; font:9px var(--mono); letter-spacing:.07em; margin-bottom:13px; }.legal-nav a { border-left:1px solid var(--line); padding:9px 12px; color:#8197b5; font-size:11px; transition:.2s; }.legal-nav a:hover,.legal-nav a.active { border-color:var(--green); color:var(--ink); background:rgba(168,207,0,.08); }.legal-content { max-width:750px; }.legal-content h2 { font-size:25px; letter-spacing:-.06em; margin:42px 0 12px; }.legal-content h2:first-of-type { margin-top:37px; }.legal-content p { color:#7f98b8; font-size:13px; line-height:1.85; margin:0 0 15px; }.legal-content a { color:var(--ink); font-weight:700; text-decoration:underline; text-underline-offset:3px; }.legal-alert { border:1px solid rgba(16, 26, 43, .2); background:#e1e4e9; padding:19px 21px; }.legal-alert strong { font:10px var(--mono); color:#6d5a16; text-transform:uppercase; letter-spacing:.06em; }.legal-alert p { margin:8px 0 0; font-size:11px; line-height:1.7; }
@media (max-width:880px) { .labs-scope,.about-intro { grid-template-columns:1fr; gap:22px; }.audience-grid { grid-template-columns:repeat(2,1fr); }.brand-list { grid-template-columns:repeat(2,1fr); }.legal-layout { gap:42px; grid-template-columns:175px minmax(0,1fr); } }
@media (max-width:600px) { .labs-scope { padding:55px 20px; }.about-intro { padding-top:78px; padding-bottom:48px; }.about-intro h2 { font-size:48px; }.about-intro>p { font-size:12px; }.audience-grid { padding-bottom:78px; }.audience-grid article { min-height:200px; padding:16px; }.audience-grid h3 { margin-top:40px; font-size:16px; }.audience-grid p { font-size:10px; }.brand-section { padding:75px 0; }.brand-list { margin-top:36px; }.brand-list span { font-size:15px; min-height:65px; padding:16px; }.legal-layout { display:block; padding-top:50px; padding-bottom:75px; }.legal-nav { position:static; display:grid; grid-template-columns:1fr 1fr; gap:1px; margin-bottom:39px; }.legal-nav>span { grid-column:1 / -1; }.legal-nav a { font-size:10px; padding:10px; border:1px solid var(--line); }.legal-content h2 { font-size:22px; margin-top:34px; }.legal-content p { font-size:12px; }.legal-alert { padding:15px; } }
@keyframes marquee{to{transform:translateX(-50%)}}@keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(16, 26, 43, .4)}50%{box-shadow:0 0 0 4px rgba(16, 26, 43, 0)}}
@media (max-width: 880px){.site-header{height:72px}.desktop-nav,.icon-button{display:none}.menu-trigger{display:grid}.menu-trigger.open span:first-child{transform:translateY(3px) rotate(45deg)}.menu-trigger.open span:last-child{transform:translateY(-3px) rotate(-45deg)}.mobile-nav{display:flex;position:fixed;inset:106px 0 auto;background:var(--ink);color:var(--cream);z-index:9;padding:20px clamp(24px,5vw,76px) 27px;flex-direction:column;transform:translateY(-130%);opacity:0;transition:transform .25s,opacity .2s;box-shadow:0 16px 20px rgba(0,0,0,.2)}.mobile-nav.open{transform:translateY(0);opacity:1}.mobile-nav a{padding:14px 0;border-bottom:1px solid rgba(230, 236, 245, .18);font-size:21px;font-weight:700;letter-spacing:-.05em;display:flex;justify-content:space-between}.mobile-nav span{color:var(--lime);font:10px var(--mono);align-self:center}.hero{grid-template-columns:1fr;min-height:auto;padding-top:153px;padding-bottom:78px}.hero-visual{min-height:420px;max-width:580px;width:100%;margin:10px auto 0}.scroll-indicator{display:none}.category-grid{grid-template-columns:repeat(2,1fr)}.category-card,.category-card:first-child,.category-card:nth-child(2),.category-card:nth-child(n+3){grid-column:span 1}.category-card:first-child{grid-column:span 2}.product-grid{grid-template-columns:repeat(2,1fr)}.assurance-process{grid-template-columns:repeat(2,1fr)}.assurance-stats{grid-template-columns:repeat(2,1fr);gap:25px}.architect-panel{grid-template-columns:1fr}.footer-top{grid-template-columns:1fr 1fr;gap:35px}.footer-contact{justify-self:start}.footer-bottom>span:last-child{display:none}}
@media (max-width: 600px){.announcement-bar{height:34px;font-size:8px}.announcement-bar a{display:none}.site-header{top:34px;padding:0 20px}.mobile-nav{inset:106px 0 auto;padding:15px 20px 21px}.brand{font-size:18px}.brand b{font-size:7px}.brand-mark{width:24px}.brand-mark i{width:6px}.hero{padding:137px 20px 50px}.hero h1{font-size:58px}.hero-copy{font-size:13px;line-height:1.75}.hero-actions{gap:18px;align-items:flex-start;flex-direction:column}.hero-footnotes{gap:22px;margin-top:47px}.hero-footnotes strong{font-size:16px}.hero-footnotes span{font-size:7px}.hero-visual{min-height:347px;transform:scale(.95);transform-origin:center bottom;margin-bottom:-12px}.orbit{width:390px;height:235px;left:50%;transform:translateX(-50%) rotate(-45deg)}.orbit-two{width:530px;height:330px;left:50%;top:28px}.server-rack{width:221px;height:370px;padding-top:28px}.rack-unit{height:46px;padding:13px}.card-top{right:0;top:65px}.card-bottom{left:0;bottom:56px}.visual-index{display:none}.marquee{height:55px}.marquee-track span{font-size:10px}.section-shell{padding-left:20px;padding-right:20px}.category-section{padding-top:82px;padding-bottom:85px}.section-heading{display:block}.section-heading h2{font-size:48px}.section-heading>p{margin-top:20px;font-size:12px}.category-grid{margin-top:43px}.category-card{min-height:215px;padding:15px}.category-icon{transform:scale(.85);transform-origin:left center;margin-bottom:20px}.category-card h3{font-size:15px}.inventory-section{padding:78px 0}.inventory-heading .button{margin-top:22px}.inventory-toolbar{margin-top:37px;padding:14px 0;align-items:flex-start}.filter-pills{gap:4px}.filter-pill{padding:7px 7px;font-size:8px}.text-button{display:none}.product-grid{grid-template-columns:1fr;margin-top:20px}.product-card{min-height:445px}.product-card-cta{min-height:300px}.assurance-section{padding-top:84px;padding-bottom:85px}.assurance-intro{display:block}.assurance-intro h2{font-size:48px}.assurance-intro>p:last-child{margin-top:22px;font-size:12px}.assurance-process{grid-template-columns:1fr;margin-top:42px}.assurance-process article{min-height:235px}.assurance-stats{margin-top:28px;gap:21px}.assurance-stats strong{font-size:24px}.assurance-stats span{font-size:7px}.architect-section{padding:0 0 0}.architect-panel{min-height:0}.architect-copy{padding:61px 26px 46px}.architect-copy h2{font-size:53px}.architect-meta{margin-top:36px;gap:14px;font-size:7px}.architecture-form{padding:35px 26px 30px}.footer-top{display:flex;flex-direction:column;min-height:0;gap:27px}.site-footer{padding:37px 20px 22px}.footer-top p{font-size:15px}.footer-bottom{display:block;line-height:1.7}.footer-bottom div{margin:10px 0;gap:15px}.quote-drawer{padding:25px 21px}.search-modal{padding-top:7vh}.search-box{width:94vw}.search-input-wrap{height:63px}.search-input-wrap input{font-size:13px}}

/* ---- Accessibility, product imagery and catalogue states ---- */
.skip-link { position:absolute; left:-9999px; top:0; z-index:100; background:var(--lime); color:var(--ink); padding:12px 18px; font:10px var(--mono); text-transform:uppercase; letter-spacing:.06em; }
.skip-link:focus { left:0; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible { outline:2px solid var(--lime); outline-offset:3px; }
body.nav-open { overflow:hidden; }
.menu-trigger span { transition:transform .2s; }

.product-image.has-img { padding:0; }
.product-image.has-img:after { display:none; }
.product-image.has-img > img { position:absolute; inset:8px 10px; margin:auto; display:block; width:auto; height:auto; max-width:calc(100% - 20px); max-height:calc(100% - 16px); object-fit:contain; }

.product-card { transition:border-color .25s, background .25s; }
.product-card-deal { background:#131d2a; box-shadow:inset 0 0 0 1px rgba(127, 178, 217, .55); }
.deal-price { color:var(--lime); font-weight:500; }
.product-card > .button { margin-top:14px; }

.inventory-page-section { padding-top:38px; }
.inventory-toolbar #catalogue-count { color:#c8cfd8; white-space:nowrap; }
.filter-pill { cursor:pointer; transition:background .2s, color .2s; }

.catalogue-empty { margin-top:34px; text-align:center; color:#91a2b9; }
.catalogue-empty p { font-size:13px; margin:0 0 18px; }

@media (max-width:600px) {
  .inventory-page-section { padding-top:26px; }
  .inventory-toolbar #catalogue-count { display:none; }
}

/* ---- Vendor brand colour ----
   Each card sets --brand from products.js (the vendor's own logo colour).
   Logos keep their real colours and sit on a light plate, because several
   contain near-black ink that would vanish on the ink-coloured cards. */
.product-card { --brand: var(--lime); border-top:3px solid transparent; }
.product-card[data-brand] { border-top-color:var(--brand); }
.product-card[data-brand]:hover { background:#141e2b; }
.product-card-deal[data-brand] { border-top-color:var(--brand); }

.brand-chip { position:absolute; z-index:2; top:10px; left:10px; height:34px; min-width:74px; padding:6px 10px; display:grid; place-items:center; background:var(--paper); border-radius:3px; box-shadow:0 2px 8px rgba(0,0,0,.4); transition:box-shadow .25s, transform .25s; }
.brand-chip img { display:block; width:auto; height:auto; max-width:74px; max-height:20px; }
.product-card:hover .brand-chip { transform:translateY(-1px); box-shadow:0 3px 12px rgba(0,0,0,.5), 0 0 0 2px var(--brand); }

/* Brand wall — used on the homepage strip and the About page */
.brand-wall { display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); gap:1px; background:var(--line); border:1px solid var(--line); margin-top:38px; }
.brand-tile { --brand: var(--muted); position:relative; background:var(--paper); min-height:104px; display:grid; place-items:center; padding:22px 18px; transition:background .25s; }
.brand-tile:before { content:""; position:absolute; left:0; right:0; bottom:0; height:3px; background:var(--brand); transform:scaleX(0); transform-origin:left; transition:transform .3s; }
.brand-tile:hover:before { transform:scaleX(1); }
.brand-tile img { max-width:118px; max-height:38px; width:auto; height:auto; filter:grayscale(1); opacity:.62; transition:filter .3s, opacity .3s; }
.brand-tile:hover img { filter:none; opacity:1; }
/* Brands we stock but hold no logo file for yet — no invented mark, no invented
   colour. Drop an SVG in assets/logos/ and add it to BRANDS to upgrade a tile. */
.brand-tile.is-text { --brand:var(--green); font-size:15px; font-weight:700; letter-spacing:-.045em; color:#8297b3; transition:color .25s; }
.brand-tile.is-text:hover { color:var(--ink); }

/* Tiles stay a light plate even on the dark About section: Fortinet, HPE and
   Supermicro all carry near-black ink that would disappear on the ink background. */
.brand-section .brand-wall { background:rgba(230, 236, 245, .2); border-color:rgba(230, 236, 245, .2); }
.brand-section .brand-tile { background:var(--paper); }
.brand-strip { padding:96px clamp(24px,8vw,132px) 104px; background:var(--paper); }
.brand-strip .section-heading > p { margin-bottom:0; }

@media (max-width:600px) {
  .brand-wall { grid-template-columns:repeat(2,1fr); margin-top:28px; }
  .brand-tile { min-height:84px; padding:16px 12px; }
  .brand-tile img { max-width:92px; max-height:30px; }
  .brand-chip { height:30px; min-width:66px; padding:5px 9px; }
  .brand-chip img { max-width:66px; max-height:18px; }
  .brand-strip { padding:70px 20px 76px; }
}

/* Real photographs fill the frame; the schematic SVGs stay letterboxed. */
.product-image.has-photo { background:#0d131c; }
.product-image.has-photo > img { inset:0; width:100%; height:100%; max-width:none; max-height:none; object-fit:cover; }
.product-image.has-photo:after { display:none; }

/* ---- FAQ (answer-engine surface) ---- */
.faq-section { padding-top:110px; padding-bottom:120px; background:var(--paper); }
.faq-list { margin-top:52px; border-top:1px solid var(--line); }
.faq-item { border-bottom:1px solid var(--line); }
.faq-item summary { list-style:none; cursor:pointer; padding:26px 48px 26px 0; position:relative; display:flex; align-items:flex-start; font-size:clamp(17px,1.7vw,21px); font-weight:700; letter-spacing:-.04em; line-height:1.3; transition:color .2s; }
.faq-item summary::-webkit-details-marker { display:none; }
.faq-item summary:hover { color:var(--steel); }
.faq-item summary i { position:absolute; right:6px; top:32px; width:15px; height:15px; }
.faq-item summary i:before, .faq-item summary i:after { content:""; position:absolute; background:var(--ink); transition:transform .25s, background .2s; }
.faq-item summary i:before { top:7px; left:0; width:15px; height:2px; }
.faq-item summary i:after { left:7px; top:0; width:2px; height:15px; }
.faq-item[open] summary { color:var(--ink); }
.faq-item[open] summary i:after { transform:rotate(90deg); }
.faq-item[open] summary i:before, .faq-item[open] summary i:after { background:var(--green); }
.faq-answer { padding:0 60px 28px 0; max-width:760px; }
.faq-answer p { margin:0; color:#7f98b8; font-size:14px; line-height:1.85; }
.faq-answer a { color:var(--ink); text-decoration:underline; text-underline-offset:3px; }

@media (max-width:600px) {
  .faq-section { padding-top:74px; padding-bottom:80px; }
  .faq-list { margin-top:34px; }
  .faq-item summary { padding:20px 34px 20px 0; }
  .faq-item summary i { right:2px; top:25px; }
  .faq-answer { padding:0 0 22px; }
  .faq-answer p { font-size:13px; }
}

/* ---- 404 ---- */
.notfound-routes { padding:0 clamp(24px,8vw,132px) 110px; display:grid; grid-template-columns:repeat(2,1fr); border-top:1px solid var(--line); border-left:1px solid var(--line); margin:96px clamp(24px,8vw,132px) 110px; padding:0; }
.notfound-route { position:relative; border-right:1px solid var(--line); border-bottom:1px solid var(--line); padding:28px 26px 34px; min-height:186px; display:flex; flex-direction:column; transition:background .25s, color .25s; }
.notfound-route:hover { background:var(--ink); color:var(--cream); }
.notfound-route span { font:9px var(--mono); color:#7d92ae; letter-spacing:.06em; }
.notfound-route h2 { font-size:23px; letter-spacing:-.05em; margin:16px 0 9px; }
.notfound-route p { margin:0; font-size:12px; line-height:1.7; color:#8197b5; max-width:300px; }
.notfound-route:hover p { color:#95a6bb; }
.notfound-route b { position:absolute; right:26px; bottom:28px; font-size:19px; font-weight:400; transition:color .25s; }
.notfound-route:hover b { color:var(--lime); }

@media (max-width:600px) {
  .notfound-routes { grid-template-columns:1fr; margin:54px 20px 70px; }
  .notfound-route { min-height:146px; padding:22px 18px 28px; }
  .notfound-route h2 { font-size:20px; }
}

/* ---- Footer (multi-column) ----
   Overrides the original single-row footer styles further up the sheet. */
.footer-main { display:grid; grid-template-columns:1.5fr 1.15fr .95fr .8fr; gap:44px; padding-bottom:44px; }
.footer-identity .footer-brand { margin-bottom:22px; }
.footer-tagline { font-size:17px; font-weight:600; letter-spacing:-.05em; line-height:1.25; margin:0 0 16px; }
.footer-meta { margin:0; color:#8098b6; font:9px/1.75 var(--mono); text-transform:uppercase; letter-spacing:.045em; }
.footer-col { display:flex; flex-direction:column; align-items:flex-start; }
.footer-col h2 { font:9px var(--mono); text-transform:uppercase; letter-spacing:.11em; color:#8198b4; margin:6px 0 20px; font-weight:400; }
.footer-col a { display:block; font-size:13px; font-weight:600; letter-spacing:-.025em; color:var(--ink); margin-bottom:16px; transition:color .2s; word-break:break-word; }
.footer-col a span { display:block; font:9px var(--mono); font-weight:400; text-transform:uppercase; letter-spacing:.07em; color:#7e93af; margin-bottom:4px; transition:color .2s; }
.footer-col a b { font-weight:400; color:var(--green); }
.footer-col a:hover { color:var(--steel); }
.footer-col a:hover span { color:var(--green); }
.footer-nav a { font-size:14px; font-weight:700; letter-spacing:-.04em; margin-bottom:13px; }
.footer-bottom a { text-decoration:underline; text-underline-offset:3px; }
.footer-bottom > span:last-child { display:block; }

@media (max-width:880px) {
  .footer-main { grid-template-columns:1fr 1fr; gap:36px 30px; }
  .footer-identity { grid-column:span 2; }
  .footer-bottom > span:last-child { display:block; }
}
@media (max-width:600px) {
  .footer-main { grid-template-columns:1fr; gap:32px; padding-bottom:32px; }
  .footer-identity { grid-column:span 1; }
  .footer-tagline { font-size:16px; }
  .footer-col a { font-size:12.5px; margin-bottom:14px; }
}

/* Restocking notice */
.empty-badge { display:inline-flex; align-items:center; gap:8px; margin-bottom:16px; padding:7px 12px; border:1px solid rgba(127, 178, 217, .42); color:var(--lime); font:9px var(--mono); text-transform:uppercase; letter-spacing:.07em; }
.empty-badge .pulse-dot { background:var(--lime); }
.catalogue-empty p { max-width:470px; margin-left:auto; margin-right:auto; }

/* ---- Brand wall: one unbroken line ----
   The auto-fit grid wrapped the last brands onto a second row. A flex strip
   keeps all vendors on a single line: they share the width on desktop, hold a
   floor width on narrow screens, and the strip scrolls horizontally instead
   of wrapping. Overrides the grid rules earlier in the sheet. */
.brand-wall { display:flex; flex-wrap:nowrap; grid-template-columns:none; overflow-x:auto; scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch; scrollbar-width:none; }
.brand-wall::-webkit-scrollbar { display:none; }
.brand-tile { flex:1 1 0; min-width:92px; min-height:96px; padding:18px 10px; scroll-snap-align:start; }
.brand-tile img { max-width:76px; max-height:28px; }

@media (max-width:880px) {
  .brand-tile { min-width:86px; min-height:88px; padding:16px 9px; }
  .brand-tile img { max-width:70px; max-height:26px; }
}
@media (max-width:600px) {
  /* Still one line — the strip scrolls rather than stacking. */
  .brand-wall { grid-template-columns:none; margin-top:28px; }
  .brand-tile { flex:0 0 auto; min-width:104px; min-height:82px; padding:14px 12px; }
  .brand-tile img { max-width:78px; max-height:26px; }
}

/* ==========================================================================
   Phone / tablet optimisation
   ========================================================================== */

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
a, button, summary, label, select, input { touch-action: manipulation; }
img, svg { max-width: 100%; }

/* iOS Safari zooms the whole page when a focused field is under 16px.
   The visual size is unchanged on desktop; this only applies on touch widths. */
@media (max-width: 880px) {
  .field-label select, .field-label input, .search-input-wrap input { font-size: 16px; }
}

/* WCAG 2.5.8 target size. Standalone controls only — links inside a sentence
   are exempt, so .labs-scope prose links are deliberately left alone.
   Padding rather than flex, so inline arrows in the footer stay on their line. */
@media (max-width: 880px) {
  .hero-actions .button-text { min-height: 44px; }
  /* Padding, not min-height: the brand is a flex row whose "LABS" suffix uses
     align-self:flex-end, so stretching the container drops it onto its own line. */
  .site-header .brand, .footer-brand { padding: 8px 0; }
  .footer-col a { padding: 8px 0; margin-bottom: 6px; }
  .footer-nav a { padding: 14px 0; margin-bottom: 0; }
  .footer-bottom div { flex-wrap: wrap; gap: 2px 18px; }
  .footer-bottom div a { display: inline-flex; align-items: center; min-height: 42px; }
  .legal-nav a { padding: 12px 0; }
}

/* The 7px labels were content, not decoration — raised to a 9px floor. */
@media (max-width: 600px) {
  .announcement-bar { font-size: 9px; }
  .brand b { font-size: 8px; }
  .hero-footnotes span { font-size: 9px; }
  .assurance-stats span { font-size: 9px; }
  .architect-meta { font-size: 9px; }
  .footer-col a span { font-size: 9px; }
  .filter-pill { font-size: 9px; padding: 9px 10px; }
}
.signal-card span { font-size: 9px; }
.visual-index { font-size: 9px; }

/* The negative margin pushed this section 5px past the viewport; body
   overflow-x:hidden was masking a real clip. Full-bleed without the overhang. */
@media (max-width: 600px) {
  .home-routes { margin: 0; padding-left: 0; padding-right: 0; }
}

/* Small phones (320–360) */
@media (max-width: 360px) {
  .hero { padding: 130px 16px 44px; }
  .hero h1 { font-size: 48px; }
  .hero-copy { font-size: 12.5px; }
  .section-shell { padding-left: 16px; padding-right: 16px; }
  .page-masthead { padding: 140px 16px 40px; }
  .page-masthead h1 { font-size: 41px; }
  .section-heading h2, .assurance-intro h2, .faq-section h2 { font-size: 38px; }
  .button { font-size: 10px; padding: 0 15px; gap: 14px; }
  .brand { font-size: 17px; }
  .site-footer { padding-left: 16px; padding-right: 16px; }
  .faq-item summary { font-size: 16px; }
}

/* Tablet portrait — two-up product grid has room for a taller image frame */
@media (min-width: 601px) and (max-width: 880px) {
  .product-card { min-height: 460px; }
  .footer-bottom { display: flex; flex-wrap: wrap; gap: 10px 24px; }
}

/* Landscape phones: the hero is 760px min-height by default, which forces
   a lot of scrolling before any content appears. */
@media (max-height: 520px) and (orientation: landscape) {
  .hero { min-height: auto; padding-top: 120px; padding-bottom: 50px; }
  .hero-visual { min-height: 300px; }
  .page-masthead { min-height: auto; padding-top: 120px; }
}

@media (max-width: 880px) {
  .footer-bottom span a { display: inline-flex; align-items: center; min-height: 34px; }
  /* Filter chips are standalone controls, so they get a real tap height. */
  .filter-pill { min-height: 42px; display: inline-flex; align-items: center; }
}

/* The wordmark must never break across lines — "LABS" was dropping below
   "NEXUSSEC" on narrow headers. */
.brand { white-space: nowrap; flex-wrap: nowrap; }
.brand b { white-space: nowrap; }

/* ---- Fixes for the stepped form's markup ----
   1. .form-step is now a <legend>. A legend shrink-wraps to its content, so the
      inherited justify-content:space-between has no free space to distribute and
      the step number ends up flush against the title. width:100% restores the
      original <div> behaviour; the gap is belt and braces.
   2. `input:focus-visible` draws a 2px ring at outline-offset:3px, i.e. 5px
      OUTSIDE the control. With no margin above, that ring cut straight through
      the field label. The ring is a keyboard-accessibility feature worth
      keeping, so make room for it instead of removing it.                      */
.architecture-form .form-step { width: 100%; gap: 14px; align-items: baseline; }
.field-label select, .field-label input { margin-top: 7px; }
.field-label input[type="checkbox"], .field-label input[type="radio"] { margin-top: 0; }

/* Banner shown when the visitor arrives from a product card. */
.form-prefill {
  margin: 0 0 24px; padding: 11px 14px;
  border-left: 2px solid var(--status-ok);
  background: rgba(53, 208, 127, .08);
  font-size: 12.5px; line-height: 1.55; color: var(--cream);
}
.form-prefill a {
  color: var(--steel); text-decoration: underline; text-underline-offset: 3px;
  white-space: nowrap;
}
.form-prefill a:hover { color: var(--cream); }

/* ---- Multi-step quote form ----
   Panels are all visible by default; .is-stepped is added by JavaScript, so a
   visitor without it sees one long form that still submits correctly. */
.architecture-form fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.architecture-form legend { padding: 0; }

.form-progress {
  display: flex; gap: 6px; list-style: none; margin: 0 0 30px; padding: 0;
  font: 9px var(--mono); text-transform: uppercase; letter-spacing: .08em;
}
.form-progress li {
  flex: 1; display: flex; align-items: center; gap: 7px; padding-bottom: 10px;
  border-bottom: 2px solid rgba(230, 236, 245, .16); color: var(--text-3);
  transition: color .25s, border-color .25s;
}
.form-progress li span {
  display: grid; place-items: center; width: 19px; height: 19px; flex: none;
  border: 1px solid currentColor; border-radius: 50%; font-size: 8px;
}
.form-progress li.is-current { color: var(--steel); border-bottom-color: var(--steel); }
.form-progress li.is-done { color: var(--status-ok); border-bottom-color: var(--status-ok); }
.form-progress li.is-done span { background: var(--status-ok); border-color: var(--status-ok); color: var(--ink); }

.is-stepped .form-panel { display: none; }
.is-stepped .form-panel.is-active { display: block; animation: panelIn .28s ease; }
@keyframes panelIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.panel-note {
  margin: -6px 0 22px; font-size: 12.5px; line-height: 1.6;
  color: var(--text-2); max-width: 46ch;
}

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.field-row .field-narrow { max-width: 130px; }
.field-label em {
  font-style: normal; font-size: 8px; font-family: var(--mono);
  letter-spacing: .08em; color: var(--status-warn); margin-left: 6px;
}
.field-label small {
  display: block; margin-top: 7px; font-size: 11px; line-height: 1.5;
  color: var(--text-3); text-transform: none; letter-spacing: 0; font-weight: 400;
}
.architecture-form input[type="text"],
.architecture-form input[type="email"],
.architecture-form input[type="tel"],
.architecture-form input[type="number"] { width: 100%; }
.architecture-form .is-invalid { border-color: var(--status-warn) !important; }

.check-group { margin: 4px 0 6px; }
.check-group legend {
  font: 9px var(--mono); text-transform: uppercase; letter-spacing: .1em;
  color: var(--text-3); margin-bottom: 12px;
}
.check-line {
  display: flex; align-items: flex-start; gap: 10px; margin-bottom: 11px;
  font-size: 12.5px; line-height: 1.5; color: var(--cream); cursor: pointer;
}
.check-line input { flex: none; width: 15px; height: 15px; margin-top: 1px; accent-color: var(--steel); }
.check-standalone { margin: 18px 0 4px; color: var(--text-2); }

.form-nav { display: flex; align-items: center; gap: 18px; margin-top: 26px; flex-wrap: wrap; }
.form-nav .button-text { color: var(--text-2); }
.form-nav .button-text:hover { color: var(--steel); }

@media (max-width: 700px) {
  .field-row { grid-template-columns: 1fr; gap: 0; }
  .field-row .field-narrow { max-width: none; }
  .form-progress { gap: 4px; font-size: 8px; }
  .form-progress li { gap: 5px; }
  .form-nav { gap: 12px; }
  .form-nav .button { width: 100%; justify-content: center; }
  .form-nav .button-text { width: auto; }
}

/* ---- Quote form: message field + honeypot ---- */
.field-label i { font-style: normal; opacity: .55; text-transform: none; letter-spacing: 0; }
.architecture-form textarea {
  width: 100%; margin-top: 9px; padding: 13px 14px; resize: vertical; min-height: 92px;
  background: rgba(255,255,255,.04); border: 1px solid rgba(230, 236, 245, .17);
  color: var(--cream); font: 13px/1.55 var(--sans); border-radius: 2px;
  transition: border-color .2s, background .2s;
}
.architecture-form textarea::placeholder { color: rgba(230, 236, 245, .34); }
.architecture-form textarea:focus { outline: none; border-color: var(--lime); background: rgba(255,255,255,.07); }

/* Honeypot: off-screen rather than display:none, because some bots skip
   hidden inputs. Kept out of the tab order and the accessibility tree. */
.hp-field {
  position: absolute !important; left: -9999px !important; top: auto !important;
  width: 1px !important; height: 1px !important; overflow: hidden !important;
}

.form-submit[disabled] { opacity: .6; cursor: progress; }

@media (max-width: 880px) {
  .architecture-form textarea { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}


/* ---- Primary action: brass ----
   Deliberately not steel. The vendor logos on this site are predominantly blue
   (Dell #0083CA, Cisco #0096D6, Sophos #007AFF, Juniper #1967BB); keeping the
   main call to action in brass stops it reading as one of them. */
.button-primary { background: var(--brass); border-color: var(--brass); color: var(--ink); }
.button-primary:hover { background: var(--brass-bright); border-color: var(--brass-bright); }
.announcement-bar { background: var(--brass); color: var(--ink); }
.announcement-bar .pulse-dot { background: var(--ink); }

/* Status colours carry their hardware meaning rather than the brand accent. */
.product-status, .status-pill { color: var(--status-ok); }
.empty-badge { border-color: rgba(245, 165, 36, .42); color: var(--status-warn); }
.empty-badge .pulse-dot { background: var(--status-warn); }

/* ---- Accessible text on the LIGHT surfaces ----
   The site alternates dark panels with light document sections. --steel and
   --brass are tuned for 8:1 on the dark panels, which leaves them at only
   2.1–2.3:1 on paper. These darker variants carry the same hue at a luminance
   that clears WCAG AA on light backgrounds. (The originals had the same problem
   before the re-theme — luminance was preserved, so this is a fix, not a
   regression.)
   Light containers, confirmed by measuring computed backgrounds:
     .site-footer .faq-section .brand-strip .architect-section .home-routes
   Dark containers keep the bright accents:
     .hero .page-masthead .inventory-section .product-card .architect-panel
     .brand-section .labs-scope .home-route                                    */
:root {
  /* Tuned against the FOOTER (#dde7f2), not --paper: the footer is the darkest
     of the light surfaces, so a value that clears AA on paper can still fail
     there. 4.9:1 on the footer, 5.5:1 on paper, 6.2:1 on white cards.
     Hue 221 is the parent's --brand, kept so it still reads as the same blue. */
  --steel-ink: #1555e1;
  --brass-ink: #6f5710;   /* brass accent on light — 6.5:1 on --paper  */
  --on-light-2: #46536a;  /* primary muted on light                    */
  --on-light-3: #455a73;  /* secondary muted on light — 5.2:1 on footer */
}

/* ---- Surface context ----
   Naming individual selectors for every accent did not hold: each new page
   introduced containers the list did not know about, and a modifier-based rule
   fails too (the hero eyebrow has no .light class yet sits on a dark panel).

   Instead the accent resolves from the SURFACE. Custom properties inherit, so a
   dark panel nested inside a light section simply resets the context back, and
   any markup added later inherits the right value without a new rule.

   The three lists below were produced by measuring computed backgrounds on all
   ten pages, not by reading the markup. */
/* The default is LIGHT, because <body> is --paper. Getting this the wrong way
   round is subtle: any section that paints no background of its own sits
   directly on the light body, and there are more of those than there are dark
   panels — so defaulting to dark silently mis-colours every one of them. */
:root {
  --accent-ctx: var(--steel-ink);
  --muted-ctx:  var(--on-light-3);
  --body-ctx:   var(--on-light-2);
  --brassy-ctx: var(--brass-ink);
}

/* Dark panels flip the context; anything nested inside inherits it */
.hero, .page-masthead, .inventory-section, .product-card, .architect-panel,
.architecture-form, .brand-section, .labs-scope, .assurance-cta, .signal-card,
.server-rack, .home-route:not(.route-architect), .quote-drawer {
  --accent-ctx: var(--steel);
  --muted-ctx:  var(--text-3);
  --body-ctx:   var(--text-2);
  --brassy-ctx: var(--green);
}

/* Surfaces filled with an accent need dark text, not a lighter accent */
.marquee, .skip-link, .toast, .announcement-bar,
.home-route.route-architect, .button-primary {
  --accent-ctx: var(--ink);
  --muted-ctx:  var(--ink);
  --body-ctx:   var(--ink);
  --brassy-ctx: var(--ink);
}

/* Everything accent-coloured now reads its surface rather than its selector */
h1 em, h2 em, h3 em { color: var(--accent-ctx); }
.eyebrow span { color: var(--brassy-ctx); }
.section-heading > p, .category-card p { color: var(--muted-ctx); }

.home-route.route-architect h2, .home-route.route-architect h2 em,
.home-route.route-architect p, .home-route.route-architect span,
.home-route.route-architect b { color: var(--ink); }

/* Must out-specify `.brand > span:last-of-type > span`, which is (0,2,2). */
.site-footer .brand > span:last-of-type > span { color: var(--accent-ctx); }
.site-footer .footer-col h2,
.site-footer .footer-col a span,
.site-footer .footer-meta,
.site-footer .footer-bottom,
.site-footer .footer-bottom span,
.site-footer .footer-bottom a { color: var(--muted-ctx); }

.faq-section p, .legal-alert p { color: var(--muted-ctx); }

/* Muted body copy that carried its own hard-coded grey and so never picked up
   the surface context. These sections paint no background, so they sit on the
   light body and need the light-surface tier. */
.assurance-process article p,
.assurance-stats span,
.audience-grid article p,
.legal-content p,
.legal-nav span,
.legal-nav a,
.notfound-route p { color: var(--muted-ctx); }
.legal-nav a.active { color: var(--ink); font-weight: 700; }

/* Two values the palette migration missed, plus one marginal contrast lift. */
.legal-nav .active { background: rgba(126, 163, 243, .10); }
.choice-grid input:checked + label { background: rgba(126, 163, 243, .08); }
.form-privacy { color: #8397b4; }   /* was #6d86a7 — 4.1:1, just under AA */
.icp-section { padding-top:118px; padding-bottom:126px; background:var(--paper); }
.icp-heading { align-items:flex-end; }
.icp-workbench { margin-top:58px; display:grid; grid-template-columns:minmax(230px,.34fr) minmax(0,1fr); border:1px solid #273955; background:var(--ink); box-shadow:0 28px 60px rgba(16,26,43,.18); }
.icp-tabs { padding:15px; border-right:1px solid #273955; background:#121d30; display:flex; flex-direction:column; gap:4px; }
.icp-tab { width:100%; min-height:74px; padding:14px 15px; border:1px solid transparent; background:transparent; color:#aab9ca; text-align:left; font:11px/1.35 var(--sans); font-weight:700; letter-spacing:-.025em; transition:background .22s,border-color .22s,color .22s,transform .22s; }
.icp-tab span { display:block; margin-bottom:6px; color:#8398b0; font:9px var(--mono); letter-spacing:.08em; }
.icp-tab:hover { color:var(--cream); background:rgba(126,163,243,.07); }
.icp-tab.active { color:var(--cream); border-color:rgba(126,163,243,.48); background:linear-gradient(105deg,rgba(126,163,243,.18),rgba(126,163,243,.045)); box-shadow:inset 3px 0 var(--brass); }
.icp-tab.active span { color:var(--brass); }
.icp-panel { min-height:454px; display:grid; grid-template-columns:minmax(0,1fr) minmax(260px,.72fr); color:var(--cream); overflow:hidden; }
.icp-panel[hidden] { display:none !important; }
.icp-copy { padding:53px clamp(28px,5vw,74px); position:relative; z-index:1; }
.icp-copy .eyebrow { margin-bottom:17px; }
.icp-copy h3 { margin:0 0 18px; font-size:clamp(31px,3.1vw,48px); letter-spacing:-.065em; line-height:.98; }
.icp-copy h3 em { color:var(--steel); font-style:normal; }
.icp-copy > p:not(.eyebrow) { max-width:470px; color:#adbbcb; font-size:13px; line-height:1.83; }
.icp-copy ul { display:grid; gap:8px; list-style:none; padding:0; margin:25px 0 31px; color:#d0d9e4; font-size:11px; }
.icp-copy li { display:flex; align-items:flex-start; gap:9px; }
.icp-copy li::before { content:"/"; color:var(--brass); font:12px var(--mono); }
.icp-signal { position:relative; min-height:454px; overflow:hidden; background:radial-gradient(circle at 49% 49%,rgba(126,163,243,.16),transparent 32%),linear-gradient(135deg,#152238,#0d1624); border-left:1px solid #273955; }
.icp-signal::before { content:""; position:absolute; inset:0; opacity:.32; background-image:linear-gradient(rgba(172,194,223,.11) 1px,transparent 1px),linear-gradient(90deg,rgba(172,194,223,.11) 1px,transparent 1px); background-size:38px 38px; mask-image:linear-gradient(145deg,transparent 4%,#000 70%); }
.icp-orbit { position:absolute; left:50%; top:50%; border:1px solid rgba(126,163,243,.42); border-radius:50%; transform:translate(-50%,-50%); }
.icp-orbit.orbit-a { width:218px; height:218px; animation:icp-pulse 3.8s ease-in-out infinite; }
.icp-orbit.orbit-b { width:332px; height:332px; border-color:rgba(201,162,39,.24); animation:icp-pulse 3.8s ease-in-out -1.4s infinite; }
.icp-core { position:absolute; z-index:1; left:50%; top:50%; width:104px; height:104px; border:1px solid var(--steel); background:#17263d; transform:translate(-50%,-50%) rotate(45deg); display:grid; place-items:center; box-shadow:0 0 0 10px rgba(126,163,243,.06),0 16px 30px rgba(0,0,0,.35); }
.icp-core b,.icp-core small { position:absolute; transform:rotate(-45deg); }
.icp-core b { top:33px; color:var(--cream); font:700 18px var(--mono); letter-spacing:-.08em; }
.icp-core small { top:58px; color:var(--brass); font:8px var(--mono); letter-spacing:.12em; }
.icp-readout,.icp-stat { position:absolute; z-index:1; border:1px solid rgba(126,163,243,.45); background:rgba(13,22,36,.8); backdrop-filter:blur(8px); }
.icp-readout { left:24px; bottom:28px; width:174px; padding:12px; }
.icp-readout span { display:block; color:#91a5bc; font:8px var(--mono); letter-spacing:.08em; }
.icp-readout strong { display:block; margin-top:6px; color:var(--cream); font:10px var(--mono); letter-spacing:-.04em; }
.icp-readout i { display:block; height:2px; margin-top:10px; background:linear-gradient(90deg,var(--brass) 68%,rgba(126,163,243,.18) 68%); }
.icp-stat { right:22px; top:29px; display:flex; align-items:center; gap:9px; padding:10px 12px; border-color:rgba(201,162,39,.45); }
.icp-stat strong { color:var(--brass); font:18px var(--mono); }
.icp-stat span { color:#b6c4d3; font:8px/1.45 var(--mono); text-transform:uppercase; letter-spacing:.04em; }
@keyframes icp-pulse { 0%,100% { opacity:.52; transform:translate(-50%,-50%) scale(.97); } 50% { opacity:1; transform:translate(-50%,-50%) scale(1.03); } }
@media (max-width:880px) { .icp-workbench { grid-template-columns:1fr; }.icp-tabs { border-right:0; border-bottom:1px solid #273955; display:grid; grid-template-columns:repeat(2,1fr); }.icp-panel { grid-template-columns:1fr minmax(270px,.68fr); }.icp-signal { min-height:100%; } }
@media (max-width:600px) { .icp-section { padding-top:78px; padding-bottom:80px; }.icp-workbench { margin-top:38px; }.icp-tabs { grid-template-columns:1fr; gap:3px; padding:10px; }.icp-tab { min-height:54px; padding:10px 12px; font-size:11px; }.icp-tab span { display:inline; margin:0 8px 0 0; }.icp-panel { grid-template-columns:1fr; min-height:0; }.icp-copy { padding:37px 22px 30px; }.icp-copy h3 { font-size:36px; }.icp-copy > p:not(.eyebrow) { font-size:12px; }.icp-copy ul { margin:21px 0 27px; }.icp-copy .button { width:100%; }.icp-signal { min-height:305px; border-left:0; border-top:1px solid #273955; }.icp-orbit.orbit-a { width:170px; height:170px; }.icp-orbit.orbit-b { width:254px; height:254px; }.icp-readout { left:16px; bottom:17px; }.icp-stat { right:16px; top:18px; } }

/* ==========================================================================
   DESIGN SYSTEM LAYER
   Added on top of the existing sheet rather than rewriting it, so the palette
   and layout are untouched and every change here is reviewable in isolation.

   Written against a measured audit of the live site:
     22 distinct font sizes, 52 distinct spacing values, 27 line-heights with
     671 elements falling back to `normal`, 12 ad-hoc shadows, and every
     transition using the browser default `ease`.
   ========================================================================== */

:root {
  /* ---- Type scale (major third, 1.25) -------------------------------------
     Replaces the ad-hoc 6.5/7/9/13/17/19/21px values with a ratio-based set.  */
  --fs-micro: 9px;     /* mono labels â€” the accessible floor, not smaller     */
  --fs-tiny:  10px;
  --fs-xs:    11.5px;
  --fs-sm:    13px;
  --fs-base:  15px;
  --fs-md:    17px;
  --fs-lg:    21px;
  --fs-xl:    27px;
  --fs-2xl:   34px;
  --fs-3xl:   43px;
  --fs-4xl:   54px;
  --fs-5xl:   68px;

  /* ---- Vertical rhythm ----
     `normal` computes near 1.2, which is too tight for 13â€“17px running text
     and is the single biggest readability problem in the audit.              */
  --lh-tight:   1.06;   /* display headings   */
  --lh-snug:    1.28;   /* sub-headings       */
  --lh-normal:  1.62;   /* body copy          */
  --lh-relaxed: 1.75;   /* long-form legal    */

  /* ---- Spacing: 4px base ---- */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;  --s-5: 20px;
  --s-6: 24px;  --s-8: 32px;  --s-10: 40px; --s-12: 48px; --s-16: 64px;
  --s-20: 80px; --s-24: 96px; --s-32: 128px;

  /* ---- Radius ---- */
  --r-xs: 2px; --r-sm: 4px; --r-md: 8px; --r-lg: 14px; --r-full: 999px;

  /* ---- Elevation ----
     A five-step scale with two layers each: a tight contact shadow plus a
     softer ambient one. Flat single shadows are what make UI look cheap.      */
  --e-1: 0 1px 2px rgba(8, 14, 26, .16);
  --e-2: 0 2px 4px rgba(8, 14, 26, .14), 0 4px 12px rgba(8, 14, 26, .10);
  --e-3: 0 4px 8px rgba(8, 14, 26, .14), 0 12px 28px rgba(8, 14, 26, .12);
  --e-4: 0 8px 16px rgba(8, 14, 26, .16), 0 24px 52px rgba(8, 14, 26, .16);
  --e-glow: 0 0 0 1px var(--steel), 0 6px 24px rgba(126, 163, 243, .28);

  /* ---- Motion ----
     Entrance decelerates, exit accelerates, and anything that moves under the
     pointer uses a spring-ish curve. All `ease` is the giveaway of an
     unconsidered interface.                                                   */
  --ease-out:    cubic-bezier(.22, .84, .32, 1);
  --ease-in:     cubic-bezier(.55, .06, .68, .19);
  --ease-spring: cubic-bezier(.34, 1.42, .48, 1);
  --ease-smooth: cubic-bezier(.4, 0, .2, 1);
  --t-fast:   140ms;
  --t-normal: 240ms;
  --t-slow:   420ms;
}

/* ---- Global typographic corrections ------------------------------------- */

body {
  line-height: var(--lh-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

p, li, dd, blockquote { line-height: var(--lh-normal); }
.legal-content p, .legal-content li { line-height: var(--lh-relaxed); }

h1, h2, h3, h4 {
  line-height: var(--lh-tight);
  text-wrap: balance;              /* stops a lone word orphaning on line 2 */
  letter-spacing: -.035em;
}
h3, h4 { line-height: var(--lh-snug); }
p { text-wrap: pretty; }

/* Specs, prices, counts and reference codes must align in a column. */
.deal-price, .product-spec, .product-details li, .filter-count,
.assurance-stats strong, .rack-unit b, .form-progress li span,
[class*="price"], [class*="count"] { font-variant-numeric: tabular-nums; }

::selection { background: var(--steel); color: var(--ink); }

/* ---- Motion: replace the blanket `ease` -------------------------------- */

a, button, .button, .product-card, .category-card, .home-route, .brand-tile,
.filter-pill, .faq-item, .field-label input, .field-label select,
.architecture-form textarea, .footer-col a, .legal-nav a, .notfound-route {
  transition-timing-function: var(--ease-out);
  transition-duration: var(--t-normal);
}

/* ---- Interaction craft -------------------------------------------------- */

/* Buttons gain a real press state; without one they feel like images. */
.button { will-change: transform; }
.button:active { transform: translateY(1px) scale(.994); transition-duration: var(--t-fast); }

.button-primary { box-shadow: var(--e-2); }
.button-primary:hover { box-shadow: var(--e-3); transform: translateY(-1px); }
.button-primary:active { box-shadow: var(--e-1); }

/* Cards lift toward the pointer and pick up the accent edge. */
.product-card, .category-card, .notfound-route {
  transition: transform var(--t-normal) var(--ease-out),
              box-shadow var(--t-normal) var(--ease-out),
              border-color var(--t-normal) var(--ease-out);
}
.product-card:hover, .notfound-route:hover {
  transform: translateY(-3px);
  box-shadow: var(--e-3);
}
.product-card:hover .product-image img { transform: scale(1.045); }
.product-image img { transition: transform var(--t-slow) var(--ease-out); }
.product-image { overflow: hidden; }

/* Links in prose get an underline that draws rather than blinks. */
.legal-content a, .faq-answer a, .quote-notice a, .labs-scope a {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  text-decoration: none;
  transition: background-size var(--t-normal) var(--ease-out);
}
.legal-content a:hover, .faq-answer a:hover,
.quote-notice a:hover, .labs-scope a:hover { background-size: 100% 1px; }

/* A focus ring that looks designed rather than bolted on. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--steel);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

/* Filter chips: the active one should read as pressed, not just coloured. */
.filter-pill { transition: background var(--t-fast) var(--ease-out),
                            color var(--t-fast) var(--ease-out),
                            border-color var(--t-fast) var(--ease-out); }
.filter-pill:active { transform: scale(.97); }

/* FAQ disclosure arrow rotates instead of swapping. */
.faq-item summary i { transition: transform var(--t-normal) var(--ease-spring); }
.faq-item[open] summary i { transform: rotate(90deg); }

/* Form fields: a clear, calm focus treatment. */
.field-label input, .field-label select, .architecture-form textarea {
  transition: border-color var(--t-normal) var(--ease-out),
              box-shadow var(--t-normal) var(--ease-out),
              background var(--t-normal) var(--ease-out);
}
.field-label input:focus, .field-label select:focus,
.architecture-form textarea:focus {
  box-shadow: 0 2px 0 -1px var(--steel);
}

/* ---- Elevation applied ---- */
.product-card { box-shadow: var(--e-1); }
.signal-card  { box-shadow: var(--e-3); }
.toast        { box-shadow: var(--e-4); }
.brand-chip   { box-shadow: var(--e-1); }

/* ---- Header: condense once the page starts scrolling ------------------- */
.site-header {
  transition: height var(--t-normal) var(--ease-out),
              background var(--t-normal) var(--ease-out),
              box-shadow var(--t-normal) var(--ease-out),
              backdrop-filter var(--t-normal) var(--ease-out);
}
.site-header.is-condensed {
  height: 62px;
  background: rgba(16, 26, 43, .86);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  box-shadow: var(--e-2);
  border-bottom-color: rgba(230, 236, 245, .12);
}

/* ---- Scroll reveal ----
   Elements start slightly low and transparent, and are released by an
   IntersectionObserver in script.js. The `.reveal-ready` class is added by
   that script, so with JavaScript disabled nothing is ever hidden.           */
.reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--t-slow) var(--ease-out),
              transform var(--t-slow) var(--ease-out);
}
.reveal-ready [data-reveal].is-visible { opacity: 1; transform: none; }
.reveal-ready [data-reveal][data-reveal-delay="1"] { transition-delay: 70ms; }
.reveal-ready [data-reveal][data-reveal-delay="2"] { transition-delay: 140ms; }
.reveal-ready [data-reveal][data-reveal-delay="3"] { transition-delay: 210ms; }

/* ---- Scrollbar ---- */
@supports selector(::-webkit-scrollbar) {
  ::-webkit-scrollbar { width: 11px; height: 11px; }
  ::-webkit-scrollbar-track { background: var(--paper); }
  ::-webkit-scrollbar-thumb {
    background: #b9c6d6; border-radius: var(--r-full);
    border: 3px solid var(--paper);
  }
  ::-webkit-scrollbar-thumb:hover { background: #8fa3bd; }
}

/* ---- Honour the user's motion preference -------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .reveal-ready [data-reveal] { opacity: 1 !important; transform: none !important; }
  .product-card:hover, .notfound-route:hover,
  .button-primary:hover, .button:active { transform: none !important; }
  .product-card:hover .product-image img { transform: none !important; }
}


/* ==========================================================================
   HOME PAGE v2
   Rebuilt around what a hardware buyer actually needs to decide: real stock
   first, then who it's for, then how the transaction works, then proof.
   Reuses the existing component classes; only the new sections are styled here.
   ========================================================================== */

/* ---- Hero -------------------------------------------------------------- */
/* .hero is itself the two-column grid; there is no inner wrapper. */
.hero-v2 { align-items: center; gap: clamp(32px, 5vw, 72px); }
.hero-v2 h1 { font-size: clamp(38px, 6vw, 74px); margin-bottom: var(--s-6); }
.hero-v2 .hero-copy { max-width: 52ch; margin-bottom: var(--s-8); }

.trust-row {
  list-style: none; margin: var(--s-10) 0 0; padding: var(--s-6) 0 0;
  border-top: 1px solid rgba(230, 236, 245, .16);
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-5);
}
.trust-row li { display: flex; flex-direction: column; gap: 3px; }
.trust-row b {
  font-size: var(--fs-md); font-weight: 800; letter-spacing: -.04em; color: var(--steel);
  font-variant-numeric: tabular-nums;
}
.trust-row span {
  font: var(--fs-micro) var(--mono); text-transform: uppercase;
  letter-spacing: .08em; color: #9db2bf; line-height: 1.45;
}

/* ---- Live stock panel --------------------------------------------------- */
.stock-panel {
  background: rgba(230, 236, 245, .05);
  border: 1px solid rgba(230, 236, 245, .16);
  border-radius: var(--r-md);
  padding: var(--s-5);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: var(--e-3);
}
.stock-panel-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-4); padding-bottom: var(--s-4);
  border-bottom: 1px solid rgba(230, 236, 245, .14);
}
.stock-panel-head p {
  margin: 0; display: flex; align-items: center; gap: 8px;
  font: var(--fs-micro) var(--mono); text-transform: uppercase;
  letter-spacing: .1em; color: var(--cream);
}
.stock-panel-head .pulse-dot { background: var(--status-ok); }
.stock-panel-head a {
  font: var(--fs-micro) var(--mono); text-transform: uppercase;
  letter-spacing: .08em; color: var(--steel); white-space: nowrap;
}
.stock-panel-head a:hover { color: var(--cream); }

.stock-list { list-style: none; margin: 0; padding: 0; }
.stock-list li { border-bottom: 1px solid rgba(230, 236, 245, .09); }
.stock-list li:last-child { border-bottom: 0; }
.stock-row {
  display: grid; grid-template-columns: 34px minmax(0, 1fr) auto;
  align-items: center; gap: var(--s-3); padding: var(--s-4) 0;
  transition: opacity var(--t-normal) var(--ease-out);
}
.stock-row:hover { opacity: .78; }
.stock-row img { width: 34px; height: 22px; object-fit: contain; filter: grayscale(1) brightness(2.4); opacity: .8; }
.stock-name { display: block; font-size: var(--fs-sm); font-weight: 700; letter-spacing: -.025em; color: var(--cream); }
.stock-spec {
  display: block; margin-top: 2px; font: var(--fs-micro) var(--mono);
  letter-spacing: .04em; color: #9db2bf;
}
.stock-price {
  font: var(--fs-xs) var(--mono); color: var(--status-ok);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.stock-price.is-quote { color: #9db2bf; }
.stock-empty { padding: var(--s-6) 0; font-size: var(--fs-sm); color: #9db2bf; }
.stock-panel-foot {
  margin: var(--s-4) 0 0; padding-top: var(--s-4);
  border-top: 1px solid rgba(230, 236, 245, .14);
  font-size: var(--fs-xs); line-height: 1.55; color: #9db2bf;
}

/* ---- Featured stock ----------------------------------------------------- */
.featured-section { padding-top: var(--s-24); padding-bottom: var(--s-20); background: var(--paper); }
.featured-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-5); margin-top: var(--s-12); }
.featured-more { margin-top: var(--s-10); }

/* ---- Segments ----------------------------------------------------------- */
.segment-section { background: var(--ink); color: var(--cream); padding: var(--s-24) 0; }
.segment-section .section-heading h2 { color: var(--cream); }
.segment-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; margin-top: var(--s-12); background: rgba(230, 236, 245, .14); border: 1px solid rgba(230, 236, 245, .14); }
.segment-card {
  background: var(--ink); padding: var(--s-8) var(--s-6) var(--s-6);
  display: flex; flex-direction: column;
  transition: background var(--t-normal) var(--ease-out);
}
.segment-card:hover { background: #16202e; }
.segment-index { font: var(--fs-micro) var(--mono); letter-spacing: .12em; color: var(--steel); }
.segment-card h3 { margin: var(--s-4) 0 var(--s-3); font-size: var(--fs-lg); letter-spacing: -.04em; color: var(--cream); }
.segment-card > p { margin: 0 0 var(--s-5); font-size: var(--fs-sm); color: #c3d0da; }
.segment-card ul { list-style: none; margin: 0 0 var(--s-6); padding: 0; display: grid; gap: 7px; }
.segment-card li {
  position: relative; padding-left: 16px; font: var(--fs-xs) var(--mono);
  letter-spacing: .03em; color: #9db2bf;
}
.segment-card li::before { content: ""; position: absolute; left: 0; top: 7px; width: 6px; height: 1px; background: var(--steel); }
.segment-card > a {
  margin-top: auto; font: var(--fs-micro) var(--mono); text-transform: uppercase;
  letter-spacing: .1em; color: var(--steel);
}
.segment-card > a:hover { color: var(--cream); }

/* ---- Process ------------------------------------------------------------ */
.process-section { padding: var(--s-24) clamp(24px, 8vw, 132px); background: var(--paper); }
.process-steps {
  list-style: none; margin: var(--s-12) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-6);
  counter-reset: step;
}
.process-steps li { position: relative; padding-top: var(--s-6); border-top: 2px solid var(--line); }
.process-steps li::after {
  content: ""; position: absolute; top: -2px; left: 0; width: 0; height: 2px;
  background: var(--steel-ink); transition: width var(--t-slow) var(--ease-out);
}
.process-steps li:hover::after { width: 100%; }
.process-num { font: var(--fs-micro) var(--mono); letter-spacing: .12em; color: var(--accent-ctx); }
.process-steps h3 { margin: var(--s-3) 0 var(--s-2); font-size: var(--fs-md); letter-spacing: -.03em; }
.process-steps p { margin: 0; font-size: var(--fs-sm); color: var(--muted-ctx); }

/* ---- Quality standard --------------------------------------------------- */
.standard-section { background: var(--ink); color: var(--cream); padding: var(--s-24) 0; }
.standard-inner { display: grid; grid-template-columns: .85fr 1.15fr; gap: clamp(32px, 6vw, 88px); align-items: start; }
.standard-copy h2 { color: var(--cream); font-size: clamp(30px, 3.6vw, 50px); margin: var(--s-4) 0 var(--s-5); }
.standard-copy > p { font-size: var(--fs-base); color: #c3d0da; margin: 0 0 var(--s-8); max-width: 42ch; }
.standard-copy .button-outline { border-color: rgba(230, 236, 245, .4); color: var(--cream); }
.standard-copy .button-outline:hover { background: var(--steel); border-color: var(--steel); color: var(--ink); }
.standard-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: rgba(230, 236, 245, .14); border: 1px solid rgba(230, 236, 245, .14); }
.standard-list li {
  background: var(--ink); padding: var(--s-6);
  display: grid; grid-template-columns: 34px minmax(0, 1fr); gap: var(--s-4) var(--s-5);
  align-items: baseline;
}
.standard-list b { font: var(--fs-micro) var(--mono); letter-spacing: .12em; color: var(--steel); }
.standard-list strong { font-size: var(--fs-md); letter-spacing: -.03em; color: var(--cream); }
.standard-list span { grid-column: 2; font-size: var(--fs-sm); color: #9db2bf; }

/* ---- FAQ preview -------------------------------------------------------- */
.faq-preview { padding-top: var(--s-24); padding-bottom: var(--s-20); background: var(--section, #dde7f2); }
.faq-preview .faq-list { margin-top: var(--s-10); border-top: 1px solid var(--line); }
.faq-more { margin-top: var(--s-8); }

/* ---- Final CTA ---------------------------------------------------------- */
.cta-band { background: var(--ink); color: var(--cream); padding: var(--s-20) 0; }
.cta-inner { display: grid; grid-template-columns: 1.25fr .75fr; gap: clamp(28px, 5vw, 72px); align-items: center; }
.cta-band h2 { color: var(--cream); font-size: clamp(30px, 3.8vw, 52px); margin: 0 0 var(--s-4); }
.cta-band p { margin: 0; font-size: var(--fs-base); color: #c3d0da; max-width: 46ch; }
.cta-actions { display: flex; flex-direction: column; gap: var(--s-4); align-items: flex-start; }
.cta-actions .button { width: 100%; justify-content: center; }

/* ---- Responsive --------------------------------------------------------- */
@media (max-width: 1080px) {
  .featured-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .process-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-8) var(--s-6); }
  .standard-inner, .cta-inner { grid-template-columns: 1fr; }
  .cta-actions { flex-direction: row; }
  .cta-actions .button { width: auto; }
}
@media (max-width: 880px) {
  .hero-v2 { grid-template-columns: 1fr; }
  .segment-grid { grid-template-columns: 1fr; }
  .trust-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4); }
}
@media (max-width: 620px) {
  .featured-grid { grid-template-columns: 1fr; }
  .process-steps { grid-template-columns: 1fr; }
  .standard-list li { grid-template-columns: 1fr; gap: var(--s-2); }
  .standard-list span { grid-column: 1; }
  .cta-actions { flex-direction: column; align-items: stretch; }
  .featured-section, .process-section, .faq-preview { padding-top: var(--s-16); padding-bottom: var(--s-12); }
  .segment-section, .standard-section { padding: var(--s-16) 0; }
}


/* ---- Register the new home-page dark surfaces ----
   The surface-context tokens only flip inside containers that are named. The
   redesign added four dark sections, and until they are listed here their
   descendants inherit the LIGHT tier — which is why the accent ems and muted
   copy rendered at ~2.5:1 on them. */
.segment-section, .standard-section, .cta-band, .stock-panel {
  --accent-ctx: var(--steel);
  --muted-ctx: #9db2bf;
  --body-ctx: #c3d0da;
  --brassy-ctx: var(--green);
  --text-1: #ffffff;
  --text-2: #c3d0da;
  --text-3: #9db2bf;
  --on-light-2: #c3d0da;
  --on-light-3: #9db2bf;
  --link: var(--steel);
  --line: rgba(230, 236, 245, .18);
  --line-strong: rgba(230, 236, 245, .38);
}
.segment-section .section-heading > p,
.standard-section .section-heading > p,
.cta-band p { color: var(--body-ctx); }
.segment-section .eyebrow, .standard-section .eyebrow { color: var(--muted-ctx); }


/* ---- Home v2 corrections ------------------------------------------------
   The product card is a DARK card, and the featured section it now sits on is
   light. Without flipping the context back, the card inherited light-surface
   text and the titles landed at 1.0:1 on their own background. */
:root { --text-1: var(--ink); }

.product-card {
  --text-1: var(--cream);
  --text-2: #c3d0da;
  --text-3: #9db2bf;
  --accent-ctx: var(--steel);
  --muted-ctx: #9db2bf;
  --body-ctx: #c3d0da;
  --brassy-ctx: var(--green);
}
.product-card h3 { color: var(--cream); }
.product-card .product-spec, .product-card .product-details p { color: #9db2bf; }

/* Outline and text buttons inherit a light-on-dark colour by default, which is
   invisible on the new light sections. Bind them to the surface context. */
.featured-section .button-outline,
.process-section .button-outline,
.faq-preview .button-text,
.featured-more, .faq-more {
  color: var(--text-1);
  border-color: var(--line-strong, #9db2bf);
}
.featured-section .button-outline:hover,
.featured-more:hover, .faq-more:hover { background: var(--ink); border-color: var(--ink); color: #fff; }

/* Quote form helper text sat at 4.24:1 — just under AA on the dark panel. */
.architecture-form .field-label small,
.architecture-form .check-line span,
.architecture-form .check-group legend,
.architecture-form li { color: #b3c2d1; }


/* ==========================================================================
   MOTION LAYER  (paired with script.js)
   Every effect below is gated behind a class that only JavaScript adds, so a
   visitor without it — or with reduced motion on — gets the finished page and
   never a hidden or half-animated one.
   ========================================================================== */

/* ---- Scroll progress ---- */
.scroll-progress {
  position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 60;
  background: var(--steel); transform-origin: 0 50%;
  transform: scaleX(var(--progress, 0));
  transition: transform 90ms linear;
  pointer-events: none;
}

/* ---- Hero entrance ---- */
.hero-enter-ready .hero-enter {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 620ms var(--ease-out) var(--enter-delay, 0ms),
              transform 620ms var(--ease-out) var(--enter-delay, 0ms);
  will-change: opacity, transform;
}
.hero-enter-ready .hero-enter.is-in { opacity: 1; transform: none; }

/* ---- Pointer spotlight ----
   Sits behind the content on its own layer; pointer-events none so it can
   never swallow a click. */
.hero.has-spotlight { position: relative; isolation: isolate; }
.hero.has-spotlight::before {
  content: "";
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(
    440px circle at var(--mx, 50%) var(--my, 40%),
    rgba(126, 163, 243, .13), transparent 68%);
  opacity: 0; transition: opacity 500ms var(--ease-out);
}
.hero.has-spotlight:hover::before { opacity: 1; }
.hero > * { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  .scroll-progress { display: none; }
  .hero-enter-ready .hero-enter { opacity: 1 !important; transform: none !important; }
  .hero.has-spotlight::before { display: none; }
}


/* ==========================================================================
   SERVER RACK — animation
   Only `transform` and `opacity` are animated, so every frame stays on the
   compositor and none of this triggers layout. Timings are deliberately
   co-prime (1.7s / 2.3s / 3.1s / 4.3s) so the LEDs never fall into a visible
   marching pattern the way equal durations do — real drive activity is
   irregular, and synchronised blinking is the thing that reads as "fake".
   ========================================================================== */

.hero-visual { perspective: 1200px; }

/* The whole rack breathes, very slightly. */
.server-rack {
  animation: rack-float 9s var(--ease-smooth, ease-in-out) infinite;
  transform-style: preserve-3d;
  will-change: transform;
}
@keyframes rack-float {
  0%, 100% { transform: translateY(0) rotateX(0deg); }
  50%      { transform: translateY(-9px) rotateX(1.1deg); }
}

/* Drive-activity LEDs. Three per unit, each on its own rhythm. */
.rack-unit span {
  animation-name: led-blink;
  animation-iteration-count: infinite;
  animation-timing-function: steps(1, end);
  will-change: opacity;
}
@keyframes led-blink {
  0%, 44%  { opacity: 1; }
  46%, 52% { opacity: .18; }
  54%, 78% { opacity: 1; }
  80%, 86% { opacity: .28; }
  88%,100% { opacity: 1; }
}
.rack-unit span:nth-child(1) { animation-duration: 1.7s; }
.rack-unit span:nth-child(2) { animation-duration: 2.3s; animation-delay: .35s; }
.rack-unit span:nth-child(3) { animation-duration: 3.1s; animation-delay: .8s; }
.unit-two   span { animation-delay: .5s; }
.unit-three span { animation-delay: 1.1s; }
.unit-four  span { animation-delay: .25s; }
.unit-five  span { animation-delay: 1.6s; }
.unit-six   span { animation-delay: .9s; }

/* The health dot on the rack label pulses like a real status LED. */
.rack-brand .status-dot { animation: status-pulse 2.6s ease-in-out infinite; }
@keyframes status-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(53, 208, 127, .55); }
  70%      { opacity: .75; box-shadow: 0 0 0 7px rgba(53, 208, 127, 0); }
}

/* A diagnostic sweep passing down the rack. */
.scan-line {
  animation: scan-sweep 5.5s var(--ease-smooth, cubic-bezier(.4,0,.2,1)) infinite;
  will-change: transform, opacity;
}
@keyframes scan-sweep {
  0%       { transform: translateY(-40px) scaleX(.4); opacity: 0; }
  12%      { opacity: .9; }
  50%      { transform: translateY(180px) scaleX(1); opacity: .9; }
  88%      { opacity: 0; }
  100%     { transform: translateY(340px) scaleX(.4); opacity: 0; }
}

/* Orbits drift in opposite directions so the background never feels static. */
.orbit-one { animation: orbit-spin 38s linear infinite; }
.orbit-two { animation: orbit-spin 52s linear infinite reverse; }
@keyframes orbit-spin { to { transform: rotate(360deg); } }

/* The two callout cards drift out of phase with the rack. */
.card-top    { animation: card-drift 7.5s ease-in-out infinite; }
.card-bottom { animation: card-drift 8.8s ease-in-out infinite reverse; }
@keyframes card-drift {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-7px); }
}

/* The progress rule inside each card fills, holds, then resets. */
.signal-card i {
  transform-origin: 0 50%;
  animation: bar-fill 6s var(--ease-out, ease-out) infinite;
}
@keyframes bar-fill {
  0%       { transform: scaleX(0); }
  35%, 85% { transform: scaleX(1); }
  100%     { transform: scaleX(1); opacity: .35; }
}

/* Pointer tilt, driven by script.js. Kept small — a big tilt reads as a toy. */
.hero-visual.has-tilt .server-rack {
  transform: rotateX(calc(var(--ty, 0) * -4deg)) rotateY(calc(var(--tx, 0) * 5deg)) translateY(0);
  animation: none;
  transition: transform 260ms var(--ease-out, ease-out);
}

@media (prefers-reduced-motion: reduce) {
  .server-rack, .rack-unit span, .rack-brand .status-dot, .scan-line,
  .orbit-one, .orbit-two, .card-top, .card-bottom, .signal-card i {
    animation: none !important;
  }
  .hero-visual.has-tilt .server-rack { transform: none !important; }
  .signal-card i { transform: scaleX(1); }
}


/* ==========================================================================
   VIRTUAL LABS + HERO VIDEO
   ========================================================================== */

/* ---- Virtual labs ---- */
.labs-section { padding-top: var(--s-24); padding-bottom: var(--s-20); background: var(--paper); }
.labs-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px; margin-top: var(--s-12);
  background: var(--line); border: 1px solid var(--line);
}
.lab-card {
  background: var(--card, #fff); padding: var(--s-8) var(--s-6) var(--s-6);
  display: flex; flex-direction: column;
  transition: background var(--t-normal) var(--ease-out),
              transform var(--t-normal) var(--ease-out);
}
.lab-card:hover { background: #fff; transform: translateY(-2px); }
.lab-tag {
  font: var(--fs-micro) var(--mono); text-transform: uppercase;
  letter-spacing: .11em; color: var(--accent-ctx);
}
.lab-card h3 {
  margin: var(--s-3) 0 var(--s-3);
  font-size: var(--fs-xl); letter-spacing: -.04em; color: var(--text-1);
}
.lab-card > p { margin: 0 0 var(--s-5); font-size: var(--fs-sm); color: var(--muted-ctx); }
.lab-card ul { list-style: none; margin: auto 0 0; padding: 0; display: grid; gap: 6px; }
.lab-card li {
  position: relative; padding-left: 15px;
  font: var(--fs-xs) var(--mono); letter-spacing: .03em; color: var(--muted-ctx);
}
.lab-card li::before {
  content: ""; position: absolute; left: 0; top: 7px;
  width: 6px; height: 1px; background: var(--accent-ctx);
}
.labs-foot {
  margin-top: var(--s-10); padding-top: var(--s-6); border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-6); flex-wrap: wrap;
}
.labs-foot p { margin: 0; max-width: 62ch; font-size: var(--fs-sm); color: var(--muted-ctx); }
.labs-foot strong { color: var(--text-1); }

/* ---- Hero ambient video ----
   Sits on its own layer behind everything, dimmed so the headline keeps its
   contrast no matter what the footage does. Until a file is supplied the
   element renders nothing and the rack illustration carries the hero. */
.hero-media {
  position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
}
.hero-media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--ink) 12%, rgba(16, 26, 43, .82) 55%, rgba(16, 26, 43, .62));
}
.hero-video {
  width: 100%; height: 100%; object-fit: cover; display: block;
  opacity: .5; filter: saturate(.75) contrast(1.05);
}
.hero.has-video .hero-visual { opacity: .35; }

@media (max-width: 880px) {
  /* Never pull video over a mobile connection; the poster is enough. */
  .hero-video { display: none; }
  .hero-media::after { background: var(--ink); }
}
@media (prefers-reduced-motion: reduce) { .hero-video { display: none; } }

/* ---- Responsive ---- */
@media (max-width: 1080px) { .labs-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px)  {
  .labs-grid { grid-template-columns: 1fr; }
  .labs-section { padding-top: var(--s-16); padding-bottom: var(--s-12); }
  .labs-foot { flex-direction: column; align-items: flex-start; }
  .labs-foot .button { width: 100%; justify-content: center; }
}


/* ==========================================================================
   BRAND WALL — horizontal marquee
   The track is cloned once by script.js, so translating exactly -50% lands on
   an identical frame and the loop is seamless. Only `transform` animates, so
   this stays on the compositor and never triggers layout.
   ========================================================================== */

.brand-wall.is-marquee {
  display: block;
  overflow: hidden;
  position: relative;
  white-space: nowrap;
  scroll-snap-type: none;
  /* Logos fade out at both edges instead of being chopped by the border. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}

.brand-wall.is-marquee .brand-track {
  display: inline-flex;
  vertical-align: top;
  animation: brand-scroll var(--marquee-duration, 40s) linear infinite;
  will-change: transform;
}

@keyframes brand-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-100%); }
}

/* Let a visitor stop the strip to actually read a logo. */
.brand-wall.is-marquee:hover .brand-track,
.brand-wall.is-marquee:focus-within .brand-track { animation-play-state: paused; }

.brand-wall.is-marquee .brand-tile {
  flex: 0 0 auto;
  min-width: 158px;
  border-right: 1px solid var(--line);
}

/* The mask already softens the ends, so the outer frame would double up. */
.brand-wall.is-marquee { border-left: 0; border-right: 0; }

@media (max-width: 620px) {
  .brand-wall.is-marquee .brand-tile { min-width: 124px; }
}

/* Reduced motion: no animation, but the strip stays swipeable so every logo
   is still reachable. The cloned set is removed from the flow so it is not
   scrolled through twice. */
@media (prefers-reduced-motion: reduce) {
  .brand-wall.is-marquee { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .brand-wall.is-marquee .brand-track { animation: none; }
  .brand-wall.is-marquee .brand-track[aria-hidden="true"] { display: none; }
}


/* ==========================================================================
   NexusSec vLabs page
   ========================================================================== */
.vlabs-masthead .trust-row { max-width: 760px; }
.vlabs-intro { padding-top: var(--s-24); padding-bottom: var(--s-20); background: var(--paper); }

/* Simulator vs real hardware — the core argument of the page, so it is set as
   a direct comparison rather than prose. */
.vlabs-compare {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px; margin-top: var(--s-12);
  background: var(--line); border: 1px solid var(--line);
}
.vlabs-compare article { background: var(--card, #fff); padding: var(--s-8) var(--s-6); }
.vlabs-compare article.is-highlight { background: var(--ink); color: var(--cream);
  --accent-ctx: var(--steel); --muted-ctx: #9db2bf; --text-1: #fff; }
.vlabs-compare h3 { margin: var(--s-3) 0 var(--s-5); font-size: var(--fs-lg);
  letter-spacing: -.04em; color: var(--text-1); }
.vlabs-compare ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.vlabs-compare li { position: relative; padding-left: 18px; font-size: var(--fs-sm);
  line-height: 1.5; color: var(--muted-ctx); }
.vlabs-compare li::before { content: ""; position: absolute; left: 0; top: 9px;
  width: 8px; height: 1px; background: var(--accent-ctx); }
.vlabs-compare .is-highlight li { color: #c3d0da; }

@media (max-width: 760px) {
  .vlabs-compare { grid-template-columns: 1fr; }
  .vlabs-intro { padding-top: var(--s-16); padding-bottom: var(--s-12); }
}


/* ==========================================================================
   NexusSec Virtual Labs (/NSVL)
   ========================================================================== */
.nsvl-masthead .trust-row { max-width: 780px; }
.nsvl-about { padding-top: var(--s-24); padding-bottom: var(--s-20); background: var(--paper); }

/* What it is / what it is not — set as a pair so the boundary is unmissable. */
.nsvl-about-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px; margin-top: var(--s-12);
  background: var(--line); border: 1px solid var(--line);
}
.nsvl-about-grid article { background: var(--card, #fff); padding: var(--s-8) var(--s-6); }
.nsvl-about-grid p { margin: var(--s-4) 0 0; font-size: var(--fs-sm); color: var(--muted-ctx); }

/* Three-way comparison: simulator / NSVL / owning the kit. */
.nsvl-compare-section { background: var(--ink); color: var(--cream); padding: var(--s-24) 0; }
.nsvl-compare-section .section-heading h2 { color: var(--cream); }
.nsvl-compare {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px; margin-top: var(--s-12);
  background: rgba(230, 236, 245, .16); border: 1px solid rgba(230, 236, 245, .16);
}
.nsvl-compare article { background: var(--ink); padding: var(--s-8) var(--s-6); }
.nsvl-compare article.is-highlight { background: #16202e; box-shadow: inset 3px 0 0 var(--steel); }
.nsvl-compare h3 { margin: 0 0 4px; font-size: var(--fs-lg); letter-spacing: -.04em; color: var(--cream); }
.compare-sub { margin: 0 0 var(--s-5); font: var(--fs-micro) var(--mono);
  text-transform: uppercase; letter-spacing: .08em; color: #9db2bf; }
.nsvl-compare ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.nsvl-compare li { position: relative; padding-left: 22px; font-size: var(--fs-sm);
  line-height: 1.5; color: #c3d0da; }
/* A tick or a dash rather than colour alone — colour is not available to
   everyone, and this list is the page's central argument. */
.nsvl-compare li.is-yes::before { content: "\2713"; position: absolute; left: 0; top: 0;
  color: var(--status-ok); font-weight: 700; }
.nsvl-compare li.is-no::before { content: "\2014"; position: absolute; left: 0; top: 0;
  color: #8b97a6; font-weight: 700; }
.nsvl-compare-note { margin: var(--s-8) 0 0; max-width: 78ch; font-size: var(--fs-sm);
  line-height: 1.65; color: #c3d0da; }
.nsvl-compare-note strong { color: var(--cream); }

/* Technology wall — static grid, deliberately not a marquee. */
.nsvl-tech { padding-top: var(--s-24); padding-bottom: var(--s-20); background: var(--section, #dde7f2); }
.tech-wall {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1px; margin-top: var(--s-12);
  background: var(--line); border: 1px solid var(--line);
}
.tech-tile {
  --brand: var(--steel-ink);
  position: relative; background: #fff; min-height: 104px;
  display: grid; place-items: center; padding: var(--s-5) var(--s-4);
  transition: background var(--t-normal) var(--ease-out);
}
.tech-tile::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: var(--brand); transform: scaleX(0); transform-origin: left;
  transition: transform var(--t-normal) var(--ease-out);
}
.tech-tile:hover::after { transform: scaleX(1); }
.tech-tile img {
  max-width: 118px; max-height: 34px; width: auto; height: auto;
  filter: grayscale(1); opacity: .66;
  transition: filter var(--t-normal) var(--ease-out), opacity var(--t-normal) var(--ease-out);
}
.tech-tile:hover img { filter: none; opacity: 1; }

.tech-groups {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px; margin-top: var(--s-8);
  background: var(--line); border: 1px solid var(--line);
}
.tech-groups article { background: var(--card, #fff); padding: var(--s-6); }
.tech-groups h3 { margin: var(--s-3) 0 var(--s-2); font-size: var(--fs-md);
  letter-spacing: -.035em; color: var(--text-1); }
.tech-groups p { margin: 0; font-size: var(--fs-sm); color: var(--muted-ctx); }
.tech-foot { margin: var(--s-8) 0 0; max-width: 80ch; font-size: var(--fs-sm);
  color: var(--muted-ctx); }
.tech-foot strong { color: var(--text-1); }

/* Why — numbered reasons */
.nsvl-why { padding-top: var(--s-24); padding-bottom: var(--s-20); background: var(--paper); }
.why-list { list-style: none; margin: var(--s-12) 0 0; padding: 0; display: grid; gap: 1px;
  background: var(--line); border: 1px solid var(--line); }
.why-list li { background: var(--card, #fff); padding: var(--s-6);
  display: grid; grid-template-columns: 54px minmax(0, 1fr); gap: var(--s-2) var(--s-4); }
.why-num { grid-row: span 2; font: var(--fs-lg) var(--mono); color: var(--accent-ctx);
  letter-spacing: -.02em; }
.why-list h3 { margin: 0; font-size: var(--fs-md); letter-spacing: -.035em; color: var(--text-1); }
.why-list p { margin: 0; font-size: var(--fs-sm); color: var(--muted-ctx); max-width: 82ch; }

@media (max-width: 1080px) {
  .tech-wall { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tech-groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nsvl-compare { grid-template-columns: 1fr; }
}
@media (max-width: 700px) {
  .nsvl-about-grid { grid-template-columns: 1fr; }
  .tech-wall { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tech-groups { grid-template-columns: 1fr; }
  .why-list li { grid-template-columns: 1fr; }
  .why-num { grid-row: auto; }
  .nsvl-about, .nsvl-tech, .nsvl-why { padding-top: var(--s-16); padding-bottom: var(--s-12); }
  .nsvl-compare-section { padding: var(--s-16) 0; }
}


/* New dark section on /NSVL — registered in the surface-context system so its
   accent and muted text resolve to the on-dark tier. Every dark container has
   to be named here; that is the one maintenance cost of this approach. */
.nsvl-compare-section {
  --accent-ctx: var(--steel);
  --muted-ctx: #9db2bf;
  --body-ctx: #c3d0da;
  --brassy-ctx: var(--green);
  --text-1: #ffffff;
  --text-2: #c3d0da;
  --text-3: #9db2bf;
  --on-light-2: #c3d0da;
  --on-light-3: #9db2bf;
  --link: var(--steel);
  --line: rgba(230, 236, 245, .18);
}
.nsvl-compare-section .section-heading > p { color: var(--body-ctx); }
.nsvl-compare-section .eyebrow { color: var(--muted-ctx); }


/* ==========================================================================
   PLATFORM ACCESS  (/NSVL #access) + header sign-in
   Two doors, weighted. The self-service card is visually primary because it
   is the right answer for most visitors; the enquiry card is deliberately
   quieter so it reads as the exception, not an equal alternative.
   ========================================================================== */
.platform-section { background: var(--ink); color: var(--cream); padding: var(--s-24) 0;
  --accent-ctx: var(--steel); --muted-ctx: #9db2bf; --body-ctx: #c3d0da;
  --brassy-ctx: var(--green); --text-1: #fff; --text-2: #c3d0da; --text-3: #9db2bf;
  --on-light-2: #c3d0da; --on-light-3: #9db2bf; --link: var(--steel);
  --line: rgba(230, 236, 245, .18); }
.platform-section .section-heading h2 { color: var(--cream); }
.platform-section .section-heading > p { color: var(--body-ctx); }
.platform-section .eyebrow { color: var(--muted-ctx); }

.access-grid { display: grid; grid-template-columns: 1.05fr .95fr;
  gap: 1px; margin-top: var(--s-12);
  background: rgba(230, 236, 245, .16); border: 1px solid rgba(230, 236, 245, .16); }
.access-card { background: var(--ink); padding: var(--s-8) var(--s-6);
  display: flex; flex-direction: column; }
.access-card.is-primary { background: #16202e; box-shadow: inset 3px 0 0 var(--steel); }
.access-tag { font: var(--fs-micro) var(--mono); text-transform: uppercase;
  letter-spacing: .1em; color: var(--steel); }
.access-card.is-primary .access-tag { color: var(--status-ok); }
.access-card h3 { margin: var(--s-3) 0 var(--s-4); font-size: var(--fs-xl);
  letter-spacing: -.04em; color: var(--cream); }
.access-card > p { margin: 0 0 var(--s-5); font-size: var(--fs-sm); color: #c3d0da; }
.access-card ul { list-style: none; margin: 0 0 var(--s-6); padding: 0; display: grid; gap: 8px; }
.access-card li { position: relative; padding-left: 18px; font-size: var(--fs-sm);
  line-height: 1.5; color: #9db2bf; }
.access-card li::before { content: ""; position: absolute; left: 0; top: 9px;
  width: 8px; height: 1px; background: var(--steel); }
.access-actions { margin-top: auto; display: flex; flex-direction: column;
  align-items: flex-start; gap: var(--s-3); }
.access-note { margin: var(--s-4) 0 0; font: var(--fs-micro) var(--mono);
  letter-spacing: .05em; color: #7f8fa3; }
.access-note b { color: #c3d0da; font-weight: 400; }
.platform-section .button-outline { border-color: rgba(230, 236, 245, .42); color: var(--cream); }
.platform-section .button-outline:hover { background: var(--steel); border-color: var(--steel); color: var(--ink); }

/* Header sign-in — a live platform needs a visible way back in. Quieter than
   the quote CTA so it does not compete with the primary commercial action. */
.header-signin {
  font: var(--fs-micro) var(--mono); text-transform: uppercase; letter-spacing: .09em;
  color: #9db2bf; margin-right: var(--s-4); white-space: nowrap;
  transition: color var(--t-fast) var(--ease-out);
}
.header-signin:hover { color: var(--steel); }
@media (max-width: 880px) { .header-signin { display: none; } }

/* The "you probably want the platform instead" banner on the enquiry form. */
.form-redirect { border-left-color: var(--steel); background: rgba(126, 163, 243, .10); }

@media (max-width: 900px) { .access-grid { grid-template-columns: 1fr; } }
@media (max-width: 620px) {
  .platform-section { padding: var(--s-16) 0; }
  .access-actions .button { width: 100%; justify-content: center; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   DEEP FIELD — the site canvas
   ═══════════════════════════════════════════════════════════════════════════

   Replaces the light document background entirely. The old site was a stack of
   opaque bands: light paper, dark panel, light paper. That reads as separate
   blocks glued together. This layer makes the whole site ONE continuous field —
   a single fixed backdrop that every section floats over — so scrolling moves
   content across a stable depth plane instead of flipping between two themes.

   Three ideas carry it:

   1. FIXED BACKDROP. The gradient lives on a position:fixed pseudo-element at
      z-index -1, not on <body>. It never scrolls and never repaints, which is
      why this stays cheap on a phone. Sections are transparent, so the same
      backdrop shows through all of them.

   2. BLUEPRINT GRID, two-tier. A 16px hairline minor grid inside a 96px major
      grid — the drafting convention for engineering drawings. On a company that
      sells rack hardware and sells lab time on it, a schematic grid says more
      than a decorative blur does.

   3. ONE LIGHT SOURCE, top-right. Every raised surface takes its highlight from
      the same direction, so the panels read as physically lit rather than as
      arbitrary boxes with borders.

   Bloom alpha is capped at .18 deliberately. Over #070c16 that peaks the
   backdrop at ~#1c273e (L .0235), which keeps the dimmest text tier
   (--text-3, lifted below) at 4.5:1 even at the brightest point of the glow.
   Raising it to .24 looks better for about a second and then fails AA in the
   top-right quadrant of every page. Measured, not guessed.
   ═════════════════════════════════════════════════════════════════════════ */

:root {
  --canvas:      #070c16;   /* the deep field itself                        */
  --canvas-peak: #1c273e;   /* backdrop at the brightest point of the bloom */
  --panel:       #101a2b;   /* raised surface, one step up from canvas      */
  --panel-2:     #16223a;   /* raised surface, two steps up (inputs, hover) */
  --chip:        #eef3f9;   /* stays LIGHT — vendor logos are drawn for it  */
  --hairline:    rgba(147, 172, 209, .16);
  --hairline-2:  rgba(147, 172, 209, .28);

  /* Sections no longer paint themselves. Both tokens resolve to nothing so
     the backdrop shows through; --section keeps a whisper of tint so
     alternating bands are still legible as bands. */
  --paper:   transparent;
  --section: rgba(126, 163, 243, .045);

  --line:   var(--hairline);
  --shadow: 0 22px 60px rgba(2, 5, 12, .55);

  /* Lifted from #7a8899. At the bloom peak the old value measured 3.6:1 —
     it passed on flat --ink and would have failed here. */
  --text-3: #93a2b5;
}

html { background: var(--canvas); }

body {
  color: var(--cream);
  background: var(--canvas);
}

/* The backdrop. Fixed, so it is painted once and never reflows. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    /* primary bloom, top-right — the single light source */
    radial-gradient(1100px 720px at 82% -6%,  rgba(126, 163, 243, .18), transparent 62%),
    /* cool counter-bloom, bottom-left, half strength */
    radial-gradient(900px  620px at -8% 92%,  rgba(14, 165, 183, .10),  transparent 66%),
    /* the field */
    var(--canvas);
}

/* The blueprint grid, on its own layer so it can be masked independently. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    /* major, 96px */
    linear-gradient(rgba(160, 190, 235, .075) 1px, transparent 1px),
    linear-gradient(90deg, rgba(160, 190, 235, .075) 1px, transparent 1px),
    /* minor, 16px */
    linear-gradient(rgba(160, 190, 235, .028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(160, 190, 235, .028) 1px, transparent 1px);
  background-size: 96px 96px, 96px 96px, 16px 16px, 16px 16px;
  /* Fades toward the bottom-left, away from the light. Without this the grid
     competes with body copy in the lower half of long pages. */
  -webkit-mask-image: radial-gradient(1200px 900px at 78% 2%, #000, transparent 76%);
          mask-image: radial-gradient(1200px 900px at 78% 2%, #000, transparent 76%);
}

/* ---- Sections become transparent ------------------------------------------
   Everything that used to paint --ink or a light fill now lets the backdrop
   through. What remains is type and hairlines over one continuous field.     */
.hero, .page-masthead-dark, .inventory-section, .labs-section, .featured-section,
.process-section, .assurance-section, .architect-section, .brand-strip,
.faq-section, .icp-section, .vlabs-intro, .nsvl-about, .nsvl-why, .home-routes,
.segment-section, .standard-section, .legal-layout, .access-section,
.platform-section, .nsvl-compare-section, .labs-scope {
  background: transparent;
}

/* Alternating bands keep a tint instead of a fill, plus hairlines to seat them. */
.faq-preview, .nsvl-tech, .segment-section, .icp-section {
  background: var(--section);
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

/* ---- Raised surfaces ------------------------------------------------------
   Panels are lit from the top-right to match the backdrop bloom: a bright
   hairline on the lit edges, a deep drop away from it.                       */
.product-card, .architect-panel, .stock-panel, .lab-card, .segment-card,
.icp-workbench, .quote-drawer, .signal-card, .nsvl-compare-section .compare-col,
.legal-alert, .form-redirect {
  background: var(--panel);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow);
}
.architecture-form, .icp-tabs { background: var(--panel-2); }

.lab-card:hover, .segment-card:hover {
  background: var(--panel-2);
  border-color: var(--hairline-2);
}

/* ---- Surface context: the default is now DARK -----------------------------
   <body> is the deep field, so any section that paints nothing inherits the
   dark tier. This is the inverse of the previous default and it has to move
   with the background or every unstyled section silently mis-colours.        */
:root {
  --accent-ctx: var(--steel);
  --muted-ctx:  var(--text-3);
  --body-ctx:   var(--text-2);
  --brassy-ctx: var(--brass);
}

/* The genuinely light surfaces that remain: logo tiles and accent-filled
   blocks. Vendor marks (Fortinet, Sophos, Cisco, Juniper) are drawn for white
   and cannot go on the field, so these stay light and flip the context back. */
.brand-tile, .brand-chip, .tech-tile, .brand-section .brand-tile {
  background: var(--chip);
  --accent-ctx: var(--steel-ink);
  --muted-ctx:  var(--on-light-3);
  --body-ctx:   var(--on-light-2);
  --brassy-ctx: var(--brass-ink);
}

/* ---- Things that were ink-on-light and are now invisible ------------------ */
.footer-brand, .footer-col a, .faq-item[open] summary,
.footer-bottom a:hover, .legal-nav a:hover, .legal-nav a.active {
  color: var(--cream);
}
.legal-content a, .faq-answer a, .quote-notice strong, .quote-notice a {
  color: var(--steel);
}
.footer-brand b { color: var(--text-2); }
.footer-brand .brand-mark i { background: var(--cream); }
.legal-alert strong { color: var(--brass); }
.legal-nav > span, .assurance-intro > p:last-child,
.assurance-process article > span { color: var(--muted-ctx); }
.legal-nav a { border-left-color: var(--hairline); }
.legal-nav a:hover, .legal-nav a.active {
  border-color: var(--brass);
  background: rgba(201, 162, 39, .09);
}

/* The assurance icons are line drawings in --ink. On the field they vanish. */
.process-icon i,
.tune-icon:before, .tune-icon:after,
.ship-icon i { background: var(--cream); }
.inspect-icon:before, .wipe-icon:before, .wipe-icon:after,
.tune-icon i, .ship-icon:before { border-color: var(--cream); }
.tune-icon:before { box-shadow: 0 29px var(--cream); }
.tune-icon i { background: var(--canvas); }
.inspect-icon:after { background: var(--brass); }

/* Outline buttons inverted: filling with --ink is invisible on the field. */
.featured-section .button-outline:hover, .featured-more:hover, .faq-more:hover {
  background: var(--steel);
  border-color: var(--steel);
  color: var(--ink);
}

/* ---- Chrome ---------------------------------------------------------------- */
.site-header { background: rgba(7, 12, 22, .72); backdrop-filter: blur(14px); }
.site-footer {
  background: rgba(126, 163, 243, .045);
  border-top: 1px solid var(--hairline);
}
.footer-bottom { border-top-color: var(--hairline); }
.faq-item { border-color: var(--hairline); }
.assurance-process, .assurance-process article { border-color: var(--hairline); }
::-webkit-scrollbar-track { background: var(--canvas); }
::-webkit-scrollbar-thumb { border-color: var(--canvas); }

/* The hero no longer needs its own dark fill or grid — the field supplies both.
   Its orbit rings stay: they are the one element that reads as equipment. */
.hero-grid, .page-masthead-dark:before { display: none; }

/* Reduce the backdrop for anyone who asked for less motion or less contrast,
   and drop the minor grid on small screens where 16px lines turn to mud. */
@media (max-width: 620px) {
  body::after {
    background-image:
      linear-gradient(rgba(160, 190, 235, .07) 1px, transparent 1px),
      linear-gradient(90deg, rgba(160, 190, 235, .07) 1px, transparent 1px);
    background-size: 64px 64px, 64px 64px;
  }
}
@media (prefers-contrast: more) {
  body::before, body::after { display: none; }
  body { background: #05080f; }
}

/* --card drives every content card on the vLabs and inventory pages; it fell
   back to #fff, which on the field read as a hole punched in the page. */
:root { --card: var(--panel); }
.lab-card, .vlabs-compare article, .nsvl-about-grid article,
.tech-groups article, .why-list li {
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow);
}
/* The logo tiles are the exception and stay light — vendor marks need it. */
.tech-tile { background: var(--chip); }

/* --text-1 is a SECOND context token, parallel to --accent-ctx, carrying
   heading colour. It defaulted to --ink for the same reason the accent context
   did: <body> used to be light. It has to flip with the background or every
   card heading resolves to #101a2b — which is now exactly the panel colour,
   so the headings measured 1.00:1 and were literally invisible. */
:root { --text-1: var(--cream); }
.brand-tile, .brand-chip, .tech-tile, .brand-section .brand-tile,
.route-architect, .marquee, .button-primary, .announcement-bar,
.skip-link, .toast { --text-1: var(--ink); }

/* The form panel darkened slightly (#18253c -> --panel-2 #16223a), which dropped
   the field underline to 2.62:1. WCAG 1.4.11 wants 3:1 on form-control
   boundaries — a border you cannot find is a field you cannot fill in. */
.field-label select, .field-label input, .field-label textarea,
.form-field input, .form-field select, .form-field textarea {
  border-bottom-color: rgba(230, 236, 245, .42);
}
.choice-grid label { border-color: rgba(230, 236, 245, .34); }

/* ═══════════════════════════════════════════════════════════════════════════
   ENTERPRISE TYPE — measured from cloudflare.com, cisco.com and sophos.com
   ═══════════════════════════════════════════════════════════════════════════
   Sampled live, not recalled:

     cloudflare.com   H1 56px / weight 500 / tracking -1.4px (-.025em) / lh .99
                      body copy 19.2px      background #151414
     cisco.com        Inter / cyan #00bceb  background #000000
     sophos.com       H1 54px / weight 300  Inter

   The dark field already matches — Cloudflare and Cisco are both dark now.
   What did not match was the type. This site was running H1 up to 104px at
   weight 800 with -.065em tracking: roughly double the size, 300 weight units
   heavier, and 2.6x tighter than Cloudflare. That reads as a startup landing
   page. Enterprise vendors are quieter and more spacious, and they set body
   copy far larger than we were.

   Manrope only ships 400+ here, so 500 is the floor — Sophos's 300 is not
   reachable without loading another weight, and 500 is the safer middle
   anyway: 300 at our heading sizes goes fragile on low-DPI Windows screens.
   ═════════════════════════════════════════════════════════════════════════ */

:root {
  /* Body copy up. Cloudflare runs 19.2px; 13px was undersized for buyers
     reading spec detail on a laptop. */
  --fs-sm:   14px;
  --fs-base: 16.5px;
  --fs-md:   18px;
  --fs-lg:   22px;
}

h1, h2, h3, h4 {
  font-weight: 500;
  letter-spacing: -.025em;
}
h1 {
  font-size: clamp(38px, 4.6vw, 64px);
  line-height: 1.0;
  margin-bottom: 24px;
}
h2 { font-size: clamp(30px, 3.4vw, 46px); line-height: 1.04; }
h3 { font-size: clamp(17px, 1.5vw, 21px); line-height: 1.25; font-weight: 600; }

/* Section headings carried their own oversized clamps from the old scale. */
.hero h1, .page-masthead h1 { font-size: clamp(38px, 4.6vw, 64px); font-weight: 500; }
.assurance-intro h2, .architect-copy h2, .home-route h2, .icp-copy h3,
.section-heading h2 { font-size: clamp(30px, 3.4vw, 46px); letter-spacing: -.025em; font-weight: 500; }

/* Lede paragraphs move up with the body scale. */
.hero-copy, .page-masthead > p:last-child, .b-lede { font-size: 17px; line-height: 1.65; }
.section-heading > p { font-size: var(--fs-base); line-height: 1.7; }

/* Weight 500 needs a touch more optical size in small headings to stay firm. */
.product-details h3, .segment-card h3, .lab-card h3, .why-list h3,
.nsvl-compare h3, .assurance-process h3 { font-weight: 600; letter-spacing: -.022em; }

/* ═══════════════════════════════════════════════════════════════════════════
   BRAND MARK — signal animation
   ═══════════════════════════════════════════════════════════════════════════
   The mark is three skewed bars. Read as a signal-strength meter, which is the
   right metaphor for a company that sells network hardware and lab time on it.

   It animates once on load, then only on hover. A logo that loops forever is a
   distraction sitting in the corner of every page — the entrance earns
   attention, the loop just spends it. Honoured for reduced-motion.
   ═════════════════════════════════════════════════════════════════════════ */

.brand-mark { overflow: hidden; }
.brand-mark i {
  transform-origin: bottom center;
  transition: height var(--t-normal, .28s) var(--ease-out, cubic-bezier(.2,.7,.3,1)),
              background var(--t-normal, .28s);
}

@media (prefers-reduced-motion: no-preference) {
  /* Entrance: bars rise in sequence.

     The stagger is baked into the KEYFRAMES rather than done with
     animation-delay + fill-mode:backwards. That earlier version had a real
     fault: `backwards` paints the `from` state (scaleY .08) during the delay,
     so any condition where the animation timeline does not advance — a
     throttled background tab at load, some in-app webviews, low-power modes —
     leaves the logo squashed to 8% height and effectively invisible.

     With fill-mode none and no delay, the element falls back to its ordinary
     style. If the animation never runs, you get the full-size mark. It fails
     to "correct logo", not to "no logo". */
  .brand-mark i:nth-child(1) { animation: mark-rise-1 .9s cubic-bezier(.2,.75,.3,1); }
  .brand-mark i:nth-child(2) { animation: mark-rise-2 .9s cubic-bezier(.2,.75,.3,1); }
  .brand-mark i:nth-child(3) { animation: mark-rise-3 .9s cubic-bezier(.2,.75,.3,1); }

  @keyframes mark-rise-1 {
    0%   { transform: scaleY(.08); opacity: 0; }
    42%  { transform: scaleY(1.14); opacity: 1; }
    69%  { transform: scaleY(1); opacity: 1; }
  }
  @keyframes mark-rise-2 {
    0%, 12% { transform: scaleY(.08); opacity: 0; }
    54%     { transform: scaleY(1.14); opacity: 1; }
    81%     { transform: scaleY(1); opacity: 1; }
  }
  @keyframes mark-rise-3 {
    0%, 24% { transform: scaleY(.08); opacity: 0; }
    66%     { transform: scaleY(1.14); opacity: 1; }
    93%     { transform: scaleY(1); opacity: 1; }
  }

  /* Hover: the bars re-level, middle bar flares to the accent. */
  .brand:hover .brand-mark i:nth-child(1) { height: 26px; }
  .brand:hover .brand-mark i:nth-child(2) { height: 12px; background: var(--brass); }
  .brand:hover .brand-mark i:nth-child(3) { height: 22px; }

  /* The wordmark accent follows. */
  .brand > span:last-of-type > span { transition: color var(--t-normal, .28s); }
  .brand:hover > span:last-of-type > span { color: var(--brass); }
}

/* The footer mark is larger and carries a slow idle pulse on the accent bar
   only — one moving element at the very bottom of the page, where it reads as
   a status light rather than as decoration. */
@media (prefers-reduced-motion: no-preference) {
  .footer-brand .brand-mark i:nth-child(2) { animation: mark-rise-2 .9s cubic-bezier(.2,.75,.3,1), mark-pulse 3.4s ease-in-out 1.2s infinite; }
  @keyframes mark-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: .45; }
  }
}

/* Three access routes now (demo / self-register / talk to us), not two.
   Two columns would orphan the third on its own row. */
@media (min-width: 1100px) {
  .access-grid { grid-template-columns: repeat(3, 1fr); }
}

/* The labs section now offers two actions — try it free, or read more. They
   need to sit side by side and stack on a phone rather than butt together. */
.labs-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4, 14px); }
.labs-foot p { flex: 1 1 320px; margin: 0; }
.labs-foot .button { flex: 0 0 auto; }
@media (max-width: 620px) {
  .labs-foot .button { width: 100%; justify-content: center; }
}

/* ---- Lab catalogue (lab-catalogue.php) ----------------------------------- */
/* Colours here are taken from the existing token set rather than invented, so
   the AA contrast measurements that cover the rest of the site still hold.
   --ink/--cream is 15.3:1; --muted is the verified light-surface body colour. */

.lab-vendor-line {
  display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5);
  margin: var(--s-8) 0 0; padding-bottom: var(--s-6);
  border-bottom: 1px solid var(--line);
}
.lab-vendor-line span {
  font: var(--fs-tiny) var(--mono); text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted-ctx);
}
.lab-vendor-line b { color: var(--ink); font-weight: 500; margin-left: 4px; }

.lab-kind-heading {
  margin: var(--s-16) 0 0; font-size: var(--fs-2xl);
  letter-spacing: -.045em; color: var(--ink); font-weight: 700;
}
.lab-kind-heading b {
  font: var(--fs-tiny) var(--mono); color: var(--muted-ctx);
  vertical-align: super; margin-left: var(--s-2); font-weight: 400;
}
.lab-kind-heading span {
  display: block; margin-top: var(--s-3); max-width: 64ch;
  font: 400 var(--fs-sm)/1.75 var(--sans); color: var(--muted-ctx);
  letter-spacing: 0;
}
.labs-grid-cat { margin-top: var(--s-8); }

/* Demo availability. The distinction is carried by the WORD, not by colour
   alone — the marker is a redundant cue, not the only one. */
.lab-card li.lab-yes  { color: #0f6b45; }
.lab-card li.lab-yes::before  { background: #0f6b45; height: 2px; top: 6px; }
.lab-card li.lab-no   { color: var(--muted-ctx); }

.lab-cta-band {
  background: var(--ink); color: var(--cream);
  padding-top: var(--s-20); padding-bottom: var(--s-20);
  display: grid; grid-template-columns: 1.2fr 1fr;
  gap: var(--s-16); align-items: end;
  --accent-ctx: var(--steel); --muted-ctx: #a3b0c2; --text-1: var(--cream);
}
.lab-cta-band h2 {
  font-size: clamp(34px, 4vw, 56px); margin: 0 0 var(--s-5);
  letter-spacing: -.05em;
}
.lab-cta-band h2 em { color: var(--steel); font-style: normal; }
.lab-cta-band p:not(.eyebrow) {
  margin: 0; max-width: 52ch; font-size: var(--fs-sm);
  line-height: 1.8; color: #a3b0c2;
}
.lab-cta-actions { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-4); }
.lab-cta-actions .button-text { color: var(--cream); }
.lab-cta-actions .button-text span { color: var(--steel); }

/* The demo link is the primary conversion action in the header, so it is the
   one thing there that reads as a button. */
.header-cta { color: var(--steel); }
.header-cta span { color: var(--steel); margin-left: 4px; }

@media (max-width: 900px) {
  .lab-cta-band { grid-template-columns: 1fr; gap: var(--s-10); }
  .lab-kind-heading { margin-top: var(--s-12); }
}

/* ============================================================================
   HOMEPAGE HERO — ANIMATED DOT-FIELD MARK
   Per design handoff "Homepage Hero Background (animated dot-field mark)".
   A field of square pixels resolves into the NexusSec Labs mark, with a
   scattered halo, a pulsing ring and a diagonal light sweep.

   There is no canvas and no rAF loop here: every dot is a plain <i> carrying
   a CSS animation, built once by script.js. Per-dot timings arrive as custom
   properties so the shorthand below is written once, not 1500 times inline.
   ========================================================================== */

.hero-field {
  position: relative;
  overflow: hidden;
  /* Navy mode. The handoff's blue alt mode is wired to the light theme below. */
  background: #0b1115;
  color: #fff;
  --dot-lit: rgb(126, 163, 243);
  --dot-dim: rgb(174, 198, 248);
  /* Full first screen, less the announcement bar that sits above it, with the
     560px floor from the handoff. svh so mobile browser chrome cannot push
     the stats row out of view. */
  min-height: 100vh;
  min-height: max(560px, calc(100svh - 38px));
}

/* ---- Dot field ---------------------------------------------------------- */

.hero-field-canvas { position: absolute; inset: 0; }

.hero-field-dot {
  position: absolute;
  border-radius: 1px;
  /* Tier as a class, not an inline colour, so a theme flip repaints the field
     without rebuilding a single node. */
  background: var(--dot-dim);
  /* Base state, so the field is still legible if either animation is off. */
  opacity: var(--o0, .5);
}
.hero-field-dot.is-lit { background: var(--dot-lit); }

/* The mark sits slightly right of and above centre. */
.hero-field-mark {
  position: absolute;
  left: 54%;
  top: 40%;
  height: 72%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
}

.hero-field-halo { position: absolute; inset: 0; }

/* Only the breathe cycle rides on the dots.

   The handoff asks for a per-dot entrance staggered left-to-right, and the
   first cut did that with `nsl-dot-in ... var(--id) backwards`. That was wrong
   for the same reason the brand-mark comment further down records: `backwards`
   paints the from-state (opacity 0, scale .4) throughout the delay, so any
   condition where the timeline does not advance — throttled background tab at
   load, low-power mode, some in-app webviews — leaves the entire mark
   invisible rather than merely un-animated. Verified: a hidden tab held every
   dot at opacity 0 indefinitely.

   The entrance now lives on the two layers instead (below), which fails to
   "mark visible", drops 640 animation instances from the page, and costs only
   the left-to-right ordering of the reveal. */
/* The duration falls back to 0s, which is how a dot opts OUT of breathing: a
   zero-length animation with no fill leaves the element on its base opacity.
   On phones the builder only emits --bd for a subset of dots, so the field
   still shimmers without paying to repaint every square each frame. */
.hero-field-mark .hero-field-dot,
.hero-field-halo .hero-field-dot {
  animation: nsl-dot-breathe var(--bd, 0s) ease-in-out var(--bg, 0s) infinite;
}

@keyframes nsl-dot-breathe {
  0%, 100% { opacity: var(--o0); }
  50%      { opacity: var(--o1); }
}

/* The field gets NO entrance fade, on purpose.

   A fade needs a 0%-opacity keyframe, and a keyframe at 0% is held for as long
   as the animation is "running" but the timeline is not advancing — which is
   the throttled/low-power/webview case. Measured here: the mark layer sat at
   opacity 0 indefinitely. For the drift below that is harmless, but for the
   layer carrying the logo it means no logo at all, so the fade is gone and the
   field is simply visible the moment the builder injects it. */
@media (prefers-reduced-motion: no-preference) {
  .hero-field-mark { animation: nsl-field-drift 18s ease-in-out infinite; }
}

@keyframes nsl-field-drift {
  0%, 100% { transform: translate(-50%, -50%) scale(1)     rotate(0deg); }
  50%      { transform: translate(-50%, -50%) scale(1.045) rotate(1.2deg); }
}

/* ---- Ring --------------------------------------------------------------- */

.hero-field-ring {
  position: absolute;
  left: 54%;
  top: 40%;
  width: 64%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, .16) 0%, rgba(255, 255, 255, 0) 62%);
  transform: translate(-50%, -50%) scale(.55);
  animation: nsl-ring-pulse 9s cubic-bezier(.25, .6, .3, 1) infinite;
}

@keyframes nsl-ring-pulse {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.55); }
  40%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.65); }
}

/* ---- Light sweep -------------------------------------------------------- */

.hero-field-sweep {
  position: absolute;
  top: -10%;
  bottom: -10%;
  left: 0;
  width: 26%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .07), transparent);
  animation: nsl-sweep 11s linear infinite;
}

@keyframes nsl-sweep {
  from { transform: translateX(-60%) skewX(-18deg); }
  to   { transform: translateX(220%) skewX(-18deg); }
}

/* ---- Vignette ----------------------------------------------------------- */

.hero-field-vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 40%, rgba(255, 255, 255, .05) 0%, transparent 58%),
    linear-gradient(180deg, rgba(4, 10, 26, .28) 0%, transparent 30%, rgba(4, 10, 26, .46) 100%);
}

/* ---- Copy --------------------------------------------------------------- */

.hero-field-copy {
  position: absolute;
  left: 56px;
  right: 56px;
  bottom: 56px;
  max-width: 560px;
  z-index: 2;
}

/* Copy entrance. The stagger is baked into five keyframes rather than done
   with animation-delay + fill-mode:backwards, for the reason the brand-mark
   block records and the field above re-learned: `backwards` paints the
   from-state through the delay, so a timeline that never advances leaves the
   headline and stats at opacity 0. Baked keyframes with no delay and no fill
   still degrade to invisible in that case, but only for the length of one
   animation rather than indefinitely — and the rule is the house pattern. */
@media (prefers-reduced-motion: no-preference) {
  .hero-field-eyebrow  { animation: nsl-rise-1 1100ms cubic-bezier(.2, .7, .3, 1); }
  .hero-field-headline { animation: nsl-rise-2 1100ms cubic-bezier(.2, .7, .3, 1); }
  .hero-field-subline  { animation: nsl-rise-3 1100ms cubic-bezier(.2, .7, .3, 1); }
  .hero-field-actions  { animation: nsl-rise-4 1100ms cubic-bezier(.2, .7, .3, 1); }
  .hero-field-stats    { animation: nsl-rise-5 1100ms cubic-bezier(.2, .7, .3, 1); }

  @keyframes nsl-rise-1 { 0%      { opacity: 0; transform: translateY(12px); } 62%, 100% { opacity: 1; transform: none; } }
  @keyframes nsl-rise-2 { 0%,  8% { opacity: 0; transform: translateY(12px); } 70%, 100% { opacity: 1; transform: none; } }
  @keyframes nsl-rise-3 { 0%, 16% { opacity: 0; transform: translateY(12px); } 78%, 100% { opacity: 1; transform: none; } }
  @keyframes nsl-rise-4 { 0%, 24% { opacity: 0; transform: translateY(12px); } 86%, 100% { opacity: 1; transform: none; } }
  @keyframes nsl-rise-5 { 0%, 32% { opacity: 0; transform: translateY(12px); } 94%, 100% { opacity: 1; transform: none; } }
}

/* Safety net, set by script.js once the entrance has had time to finish. In an
   environment where the timeline never advances, the keyframes above would hold
   the headline and the CTAs at opacity 0 forever; timers still fire there, so
   this pins the settled state and the copy cannot be lost. */
.hero-field.is-settled .hero-field-copy > * {
  animation: none;
  opacity: 1;
  transform: none;
}

.hero-field .hero-field-eyebrow {
  margin: 0 0 26px;
  font: 400 12px/1.4 var(--mono);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .72);
}

.hero-field .hero-field-headline {
  margin: 0 0 20px;
  font: 600 38px/1.14 var(--sans);
  letter-spacing: -.015em;
  color: #fff;
}

.hero-field .hero-field-subline {
  margin: 0 0 26px;
  max-width: 460px;
  font: 400 16px/1.6 var(--sans);
  color: rgba(255, 255, 255, .74);
}

/* Not in the handoff — the two conversion links the old hero carried.
   Remove this block and the matching markup to land the spec exactly. */
.hero-field-actions {
  display: flex;
  align-items: center;
  gap: 24px;
  margin-bottom: 30px;
}
.hero-field-actions .button-text { color: #fff; }
.hero-field-actions .button-text span { color: var(--steel); }

.hero-field-stats {
  display: flex;
  gap: 36px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.hero-field-stats li { display: flex; flex-direction: column; gap: 6px; }
.hero-field-stats b {
  font: 600 22px/1 var(--sans);
  letter-spacing: -.015em;
  color: #fff;
}
.hero-field-stats span {
  font: 400 11px/1.3 var(--mono);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .6);
}

/* ---- Responsive --------------------------------------------------------- */
/* The handoff specifies desktop only. Below 900px the copy leaves the corner
   and stacks in flow, and the mark is sized by width so it cannot be cropped
   away on a narrow, tall viewport. */

@media (max-width: 1100px) {
  .hero-field-copy { left: 40px; right: 40px; bottom: 48px; }
}

@media (max-width: 900px) {
  .hero-field {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 150px 24px 48px;
    min-height: max(520px, calc(100svh - 38px));
  }
  .hero-field-copy { position: static; max-width: none; }
  .hero-field-mark { width: 86%; height: auto; top: 34%; left: 50%; }
  .hero-field-ring { width: 96%; top: 34%; left: 50%; }
  .hero-field .hero-field-headline { font-size: 32px; }
  .hero-field .hero-field-subline { font-size: 15px; }
}

@media (max-width: 600px) {
  .hero-field { padding: 132px 20px 44px; min-height: max(520px, calc(100svh - 34px)); }
  .hero-field .hero-field-eyebrow { font-size: 10px; letter-spacing: .18em; margin-bottom: 20px; }
  .hero-field .hero-field-headline { font-size: 30px; }
  .hero-field-actions { flex-direction: column; align-items: flex-start; gap: 16px; }
  .hero-field-stats { gap: 22px; flex-wrap: wrap; }
  .hero-field-stats b { font-size: 19px; }
  .hero-field-stats span { font-size: 9px; letter-spacing: .12em; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-field-mark,
  .hero-field-ring,
  .hero-field-sweep,
  .hero-field-dot,
  .hero-field-copy > * {
    animation: none;
  }
  .hero-field-ring { opacity: .5; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LIGHT THEME
   ═══════════════════════════════════════════════════════════════════════════

   Opt-in via data-theme="light" on <html>. The DEEP FIELD block above turned
   this site into one continuous dark field; this block turns it back, without
   touching any of the rules in between.

   It leans on two things that were already in the stylesheet:

   1. THE *-ctx SYSTEM. --accent-ctx / --muted-ctx / --body-ctx / --brassy-ctx
      already have a documented on-light set (--steel-ink, --on-light-2/3,
      --brass-ink). Pointing the four tokens back at those values re-lights
      every component that was written to respect surface context.

   2. --cream MEANS "PRIMARY FOREGROUND", not "a light colour". 57 rules use it
      as text and only 5 as a fill — and 4 of those 5 are decorative bars and
      icon strokes that SHOULD darken on a light surface. So flipping it to ink
      does the right thing in 61 of 62 places; .quote-drawer is the exception
      and is patched below.

   Two accent tokens need care, because each is used both as ink and as a fill:

   - --brass is gold. As text on white it measures 2.1:1, so the token flips to
     --brass-ink (#6f5710) and the two rules that use it as a FILL (the primary
     button and the announcement bar) are pinned back to gold explicitly.
   - --steel goes the other way: #7ea3f3 is tuned for a dark ground and drops to
     2.2:1 on white, so it flips to #1555e1. That is dark enough to need light
     text wherever it is a fill, which is the last block here.
   ═══════════════════════════════════════════════════════════════════════════ */

:root[data-theme="light"] {
  /* ---- Surfaces ---- */
  --canvas:      #f4f7fb;
  --canvas-peak: #dee2f0;   /* backdrop under the strongest part of the tint */
  --panel:       #ffffff;
  --panel-2:     #eaf0f9;
  --chip:        #ffffff;
  --hairline:    rgba(16, 26, 43, .14);
  --hairline-2:  rgba(16, 26, 43, .26);
  --section:     rgba(21, 85, 225, .045);
  --shadow:      0 18px 44px rgba(16, 26, 43, .10);

  /* ---- Foreground ----
     --cream is the primary foreground token; on this ground that is ink. */
  --cream:  #101a2b;
  --text-1: #101a2b;
  --text-2: #46536a;
  --text-3: #455a73;

  /* ---- Accents ---- */
  --lime:       #1555e1;
  --steel:      #1555e1;
  --steel-dim:  #0f3fa8;
  --brass:      #6f5710;
  --green:      #6f5710;
  --info:       #0a7683;

  /* ---- Surface context flips back to the on-light set ---- */
  --accent-ctx: var(--steel-ink);
  --muted-ctx:  var(--on-light-3);
  --body-ctx:   var(--on-light-2);
  --brassy-ctx: var(--brass-ink);

  /* ---- Elevation: shadows on a light ground must be far lighter ---- */
  --e-1: 0 1px 2px rgba(16, 26, 43, .07);
  --e-2: 0 2px 4px rgba(16, 26, 43, .06), 0 4px 12px rgba(16, 26, 43, .05);
  --e-3: 0 4px 8px rgba(16, 26, 43, .07), 0 12px 28px rgba(16, 26, 43, .06);
  --e-4: 0 8px 16px rgba(16, 26, 43, .08), 0 24px 52px rgba(16, 26, 43, .08);
  --e-glow: 0 0 0 1px var(--steel), 0 6px 24px rgba(21, 85, 225, .20);
}

/* ---- Backdrop: same two-bloom construction, tinting instead of glowing ---- */
[data-theme="light"] body::before {
  background:
    radial-gradient(1100px 720px at 82% -6%, rgba(21, 85, 225, .10), transparent 62%),
    radial-gradient(900px  620px at -8% 92%, rgba(14, 165, 183, .07), transparent 66%),
    var(--canvas);
}

/* The blueprint grid has to darken rather than lighten, or it disappears. */
[data-theme="light"] body::after {
  background-image:
    linear-gradient(rgba(16, 26, 43, .055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(16, 26, 43, .055) 1px, transparent 1px),
    linear-gradient(rgba(16, 26, 43, .022) 1px, transparent 1px),
    linear-gradient(90deg, rgba(16, 26, 43, .022) 1px, transparent 1px);
}

/* ---- Chrome ---- */
[data-theme="light"] .site-header { background: rgba(244, 247, 251, .72); }
[data-theme="light"] .site-footer { background: rgba(21, 85, 225, .045); }
[data-theme="light"] ::-webkit-scrollbar-track { background: var(--canvas); }
[data-theme="light"] ::-webkit-scrollbar-thumb { border-color: var(--canvas); }

/* Vendor marks are drawn for white, so their tiles need a hairline to sit on
   now that the tile and the panel behind it are both white. */
[data-theme="light"] .brand-tile,
[data-theme="light"] .brand-chip,
[data-theme="light"] .tech-tile { border: 1px solid var(--hairline); }

/* ---- The two rules where --brass is a FILL, pinned back to gold ---- */
[data-theme="light"] .button-primary,
[data-theme="light"] .announcement-bar {
  background: #c9a227;
  border-color: #c9a227;
  color: var(--ink);
  --text-1: var(--ink);
}
[data-theme="light"] .button-primary:hover { background: var(--brass-bright); border-color: var(--brass-bright); }

/* ---- Where --steel is a FILL it is now dark, so its text must go light ---- */
[data-theme="light"] .marquee,
[data-theme="light"] .skip-link,
[data-theme="light"] .button-outline:hover,
[data-theme="light"] .featured-section .button-outline:hover,
[data-theme="light"] .featured-more:hover,
[data-theme="light"] .faq-more:hover {
  color: #fff;
  --text-1: #fff;
}
[data-theme="light"] ::selection { background: var(--steel); color: #fff; }

/* The one --cream fill that is a surface rather than a mark. */
[data-theme="light"] .quote-drawer { background: #fff; color: var(--ink); }

/* Inputs: the dark theme lightened these borders; on light they must darken. */
[data-theme="light"] .field-label select,
[data-theme="light"] .field-label input,
[data-theme="light"] .field-label textarea,
[data-theme="light"] .form-field input,
[data-theme="light"] .form-field select,
[data-theme="light"] .form-field textarea { border-bottom-color: rgba(16, 26, 43, .34); }
[data-theme="light"] .choice-grid label { border-color: rgba(16, 26, 43, .26); }

/* The architecture form is a dark inset panel in both themes' source; on light
   it becomes a tinted one so the fields inside stay legible. */
[data-theme="light"] .architecture-form { background: var(--panel-2); }

/* ---- Hero: the handoff's blue alt mode ----
   Reusing it here means the light theme's hero keeps white type on a saturated
   ground, so the one element with the most text over imagery needs no new
   contrast work at all. */
[data-theme="light"] .hero-field {
  background: #1555e1;
  --dot-lit: #ffffff;
  --dot-dim: #e6ecf5;
}
[data-theme="light"] .hero-field-vignette {
  background:
    radial-gradient(120% 90% at 50% 40%, rgba(255, 255, 255, .10) 0%, transparent 58%),
    linear-gradient(180deg, rgba(6, 32, 96, .20) 0%, transparent 30%, rgba(6, 32, 96, .34) 100%);
}
[data-theme="light"] .hero-field-actions .button-text { color: #fff; }
[data-theme="light"] .hero-field-actions .button-text span { color: #fff; }

/* ---- The toggle itself ---- */
.theme-toggle {
  border: 0;
  background: transparent;
  color: inherit;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: var(--r-sm);
  transition: background .2s, color .2s;
}
.theme-toggle:hover { background: var(--hairline); color: var(--steel); }
.theme-toggle svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
/* Show the destination, not the current state: dark theme offers the sun. */
.theme-toggle .icon-sun { display: block; }
.theme-toggle .icon-moon { display: none; }
[data-theme="light"] .theme-toggle .icon-sun { display: none; }
[data-theme="light"] .theme-toggle .icon-moon { display: block; }

/* ---- Light theme, part 2: dark islands and the on-dark greys --------------
   Several sections paint var(--ink) directly and are NOT in the "sections
   become transparent" list, so they stay dark even on a light page — which is
   the right look: a dark CTA band on light paper is a deliberate contrast
   band, not a bug. What breaks is the text inside them, because --cream and
   the muted greys flipped underneath.

   So these get the on-dark palette handed back as local custom properties.
   Everything nested inherits it, which means the hardcoded-grey rules below
   can be rewritten once as var(--text-2) / var(--text-3) and resolve correctly
   on BOTH grounds: dark values inside an island, light values everywhere else.
   ------------------------------------------------------------------------- */

[data-theme="light"] .page-masthead-dark,
[data-theme="light"] .assurance-cta,
[data-theme="light"] .brand-section,
[data-theme="light"] .vlabs-compare article,
[data-theme="light"] .cta-band,
[data-theme="light"] .standard-list li,
[data-theme="light"] .access-card,
[data-theme="light"] .nsvl-compare article,
[data-theme="light"] .vlabs-compare article.is-highlight,
[data-theme="light"] .home-route,
[data-theme="light"] .notfound-route:hover {
  --cream:      #e6ecf5;
  --text-1:     #e6ecf5;
  --text-2:     #c3d0da;
  --text-3:     #9db2bf;
  --steel:      #7ea3f3;
  --lime:       #7ea3f3;
  --brass:      #c9a227;
  --green:      #c9a227;
  --accent-ctx: #7ea3f3;
  --muted-ctx:  #9db2bf;
  --body-ctx:   #c3d0da;
  --brassy-ctx: #c9a227;
  --hairline:   rgba(147, 172, 209, .16);
  --hairline-2: rgba(147, 172, 209, .28);
  color: #e6ecf5;
}

/* This one is an accent panel rather than an ink panel. --lime is re-darkened
   above for the island, so it needs its ground stated explicitly. */
[data-theme="light"] .home-route.route-architect { background: #0f3fa8; }

/* ---- The on-dark greys, routed through tokens ---- */
[data-theme="light"] .eyebrow,
[data-theme="light"] .eyebrow.light { color: var(--muted-ctx); }

[data-theme="light"] .trust-row span,
[data-theme="light"] .stock-spec,
[data-theme="light"] .stock-price.is-quote,
[data-theme="light"] .stock-empty,
[data-theme="light"] .stock-note,
[data-theme="light"] .product-card .product-spec,
[data-theme="light"] .product-card .product-details p,
[data-theme="light"] .product-details ul,
[data-theme="light"] .product-topline,
[data-theme="light"] .filter-pill,
[data-theme="light"] .segment-card li,
[data-theme="light"] .standard-list span { color: var(--text-3); }

[data-theme="light"] .faq-answer p,
[data-theme="light"] .legal-content p { color: var(--text-2); }

[data-theme="light"] .in-stock { color: var(--brassy-ctx); }

/* ---- Hero blue mode: white at 60–74% is tuned for near-black, not for a
   saturated blue. Raised until every tier clears AA on #1555e1. ---- */
[data-theme="light"] .hero-field .hero-field-eyebrow { color: rgba(255, 255, 255, .88); }
[data-theme="light"] .hero-field .hero-field-subline { color: rgba(255, 255, 255, .92); }
[data-theme="light"] .hero-field-stats span { color: rgba(255, 255, 255, .9); }

/* ---- ...and the mirror case ------------------------------------------------
   Some containers declare the on-dark token tier for the dark redesign but are
   LIGHT on a light page: the tinted bands read as a wash over the canvas, and
   every raised panel is white. Measured in the browser rather than read off the
   cascade, because .segment-section is repainted by a later rule than the one
   that darkened it. These reset the tier to the on-light values. */

[data-theme="light"] .segment-section,
[data-theme="light"] .standard-section,
[data-theme="light"] .platform-section,
[data-theme="light"] .nsvl-compare-section,
[data-theme="light"] .stock-panel,
[data-theme="light"] .product-card,
[data-theme="light"] .segment-card,
[data-theme="light"] .lab-card,
[data-theme="light"] .architect-panel,
[data-theme="light"] .icp-workbench,
[data-theme="light"] .signal-card,
[data-theme="light"] .legal-alert,
[data-theme="light"] .form-redirect,
[data-theme="light"] .nsvl-compare-section .compare-col {
  --cream:      #101a2b;
  --text-1:     #101a2b;
  --text-2:     #46536a;
  --text-3:     #455a73;
  --steel:      #1555e1;
  --lime:       #1555e1;
  --brass:      #6f5710;
  --green:      #6f5710;
  --accent-ctx: #1555e1;
  --muted-ctx:  #455a73;
  --body-ctx:   #46536a;
  --brassy-ctx: #6f5710;
  --on-light-2: #46536a;
  --on-light-3: #455a73;
  --line:        rgba(16, 26, 43, .14);
  --line-strong: rgba(16, 26, 43, .30);
}

/* The sign-in link is the one piece of header chrome with its own grey. */
[data-theme="light"] .header-signin { color: var(--text-3); }

/* The architect route pins its text to --ink because its ground is the pale
   accent on dark. On light that ground is a deep blue, so the text inverts. */
[data-theme="light"] .home-route.route-architect h2,
[data-theme="light"] .home-route.route-architect h2 em,
[data-theme="light"] .home-route.route-architect p,
[data-theme="light"] .home-route.route-architect span,
[data-theme="light"] .home-route.route-architect b { color: #e6ecf5; }

/* Two body-copy rules that hardcode the on-dark grey on now-light surfaces. */
[data-theme="light"] .segment-card > p,
[data-theme="light"] .standard-copy > p { color: var(--text-2); }

/* The masthead band is transparent in the dark theme because the canvas is
   already dark. On light it has to paint again: every masthead type rule was
   written for an ink ground, and this keeps all seven inner pages opening on
   the band the design intends. */
[data-theme="light"] .page-masthead-dark { background: var(--ink); }

/* Active filter pill is a solid steel fill, which is dark on this theme. */
[data-theme="light"] .filter-pill.active { color: #fff; }

/* ---- The last of the on-dark muted copy ----------------------------------
   Same treatment as the block above: swap the literal for the token, so each
   rule resolves to the on-light tier by default and to the on-dark tier when
   it happens to sit inside one of the islands (the masthead paragraph is the
   clearest case — it is the same rule on both grounds). */
[data-theme="light"] .text-button,
[data-theme="light"] .inventory-toolbar #catalogue-count,
[data-theme="light"] .inventory-note,
[data-theme="light"] .labs-scope > p,
[data-theme="light"] .section-heading > p,
[data-theme="light"] .assurance-intro > p:last-child,
[data-theme="light"] .drawer-footer p,
[data-theme="light"] .architect-support p:last-child,
[data-theme="light"] .about-intro > p,
[data-theme="light"] .quote-notice p,
[data-theme="light"] .architecture-form li,
[data-theme="light"] .architect-meta,
[data-theme="light"] .field-label,
[data-theme="light"] .page-masthead > p:last-child,
[data-theme="light"] .architect-copy > p:not(.eyebrow),
[data-theme="light"] .card-index,
[data-theme="light"] .notfound-route span,
[data-theme="light"] .footer-col a span { color: var(--text-2); }

[data-theme="light"] .field-label input::placeholder { color: var(--text-3); }

/* The required marker is --status-warn amber: 8.9:1 on ink, 1.8:1 on the light
   form panel. Darkened for this ground only. */
[data-theme="light"] .field-label em { color: #8a5300; }
[data-theme="light"] .architecture-form li small,
[data-theme="light"] .field-label small { color: var(--text-3); }
[data-theme="light"] .nsvl-compare-note { color: var(--text-2); }

/* ═══════════════════════════════════════════════════════════════════════════
   BRAND LOADER — the mark, working
   ═══════════════════════════════════════════════════════════════════════════
   The three skewed bars, cycling. Same geometry and colour split as
   .brand-mark (middle bar on the accent), so a loading state reads as the logo
   rather than as a generic spinner.

   It follows the rule the entrance animation above already learned the hard
   way: the stagger is baked into three separate keyframes, with NO delay and
   NO fill-mode. If the animation timeline never advances — throttled
   background tab, low-power mode, some in-app webviews — every bar sits at its
   ordinary height and you get the correct static mark. It fails to "logo",
   never to "squashed sliver".

   Sizing is driven by three custom properties so one component covers a 15px
   button spinner and a 44px page-region loader.
   ═════════════════════════════════════════════════════════════════════════ */

.nsl-loader {
  display: inline-flex;
  align-items: center;
  flex: none;
  gap: var(--nsl-load-gap, 2px);
  height: var(--nsl-load-h, 28px);
  transform: skewY(-24deg);
}
.nsl-loader i {
  display: block;
  width: var(--nsl-load-w, 7px);
  border-radius: 1px;
  background: currentColor;
  transform-origin: bottom center;
}
/* Height ratios lifted from .brand-mark: 18 / 26 / 12 in a 28px box. */
.nsl-loader i:nth-child(1) { height: 64%; }
.nsl-loader i:nth-child(2) { height: 93%; background: var(--accent-ctx, var(--steel)); }
.nsl-loader i:nth-child(3) { height: 43%; }

.nsl-loader--sm { --nsl-load-h: 15px; --nsl-load-w: 4px;  --nsl-load-gap: 1.5px; }
.nsl-loader--lg { --nsl-load-h: 44px; --nsl-load-w: 11px; --nsl-load-gap: 3px; }

@media (prefers-reduced-motion: no-preference) {
  .nsl-loader i:nth-child(1) { animation: nsl-load-1 1.15s cubic-bezier(.4, 0, .6, 1) infinite; }
  .nsl-loader i:nth-child(2) { animation: nsl-load-2 1.15s cubic-bezier(.4, 0, .6, 1) infinite; }
  .nsl-loader i:nth-child(3) { animation: nsl-load-3 1.15s cubic-bezier(.4, 0, .6, 1) infinite; }

  @keyframes nsl-load-1 { 0%, 100% { transform: scaleY(1); } 16% { transform: scaleY(.32); } 42% { transform: scaleY(1.16); } }
  @keyframes nsl-load-2 { 0%, 100% { transform: scaleY(1); } 33% { transform: scaleY(.32); } 59% { transform: scaleY(1.16); } }
  @keyframes nsl-load-3 { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(.32); } 76% { transform: scaleY(1.16); } }
}

/* Reduced motion still needs a "something is happening" cue, so it gets an
   opacity pulse — no movement, no scaling. */
@media (prefers-reduced-motion: reduce) {
  .nsl-loader { animation: nsl-load-fade 1.6s ease-in-out infinite; }
  @keyframes nsl-load-fade { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
}

/* ---- Block loader, for a region or a whole panel ---- */
.nsl-loading {
  display: grid;
  place-items: center;
  gap: var(--s-4);
  min-height: 170px;
  padding: var(--s-10) 0;
  text-align: center;
}
.nsl-loading p {
  margin: 0;
  font: var(--fs-micro) var(--mono);
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--muted-ctx);
}

/* ---- Busy buttons ----
   The loader is present in the markup only while busy, and the button's width
   is pinned at the moment it flips, so swapping "Send request" for "Sending"
   cannot reflow the row it sits in. */
.button.is-busy,
.p-btn.is-busy {
  pointer-events: none;
  gap: 12px;
}
/* The arrow glyph would read as a second, contradictory affordance mid-request. */
.button.is-busy > span[aria-hidden="true"]:not(.nsl-loader) { display: none; }

/* On a filled button the mark goes monochrome. The accent bar's steel is tuned
   for a dark ground and drops to ~1.8:1 on the brass fill, and --accent-ctx
   resolves to ink here anyway, so all three bars take the button's own colour
   and the mark reads as a solid silhouette instead of a muddy two-tone. */
.button .nsl-loader i,
.p-btn .nsl-loader i { background: currentColor; }

/* ---- Mobile: the toggle becomes a thumb target ----
   38px matches the other header icon buttons on a mouse-driven layout, but it
   is under the 44px that touch guidance asks for, and this control sits right
   beside the menu trigger. */
@media (max-width: 880px) {
  .theme-toggle { width: 44px; height: 44px; }
  .theme-toggle svg { width: 20px; height: 20px; }
}

/* The grids are CSS grid, so their loading placeholder has to span all tracks
   instead of sitting in the first cell. Both grids are filled with
   replaceChildren(), which removes this automatically once stock renders. */
.product-grid > .nsl-loading { grid-column: 1 / -1; }
