/* TOWR public website — design tokens and shared component styles.
   Recreated from the approved Claude Design handoff
   (design-handoffs/TOWR Website v1.zip, draft-approved by the owner).
   Exact copy and structure preserved from the .dc.html source files;
   only the implementation (React-like DC components -> plain HTML/CSS/JS)
   has changed, matching this project's own house style (vanilla JS, no
   build step) and the handoff's own instruction to "recreate ... using
   the target codebase's established patterns." */

/* Archivo + IBM Plex Mono load via Google Fonts (see the <link> in each
   page's <head>) for this v1 build - matching the approved design files
   exactly. The handoff's own README flags self-hosting as a pre-launch
   production step (PEM-315/316 already gate going publicly live on
   hosting + legal decisions Ethan hasn't made yet); this is not a build
   blocker, just a known follow-up before towr.tools actually goes live. */

:root{
  --ink:#14202E;
  --ink-2:#3E4C5E;
  --muted:#7A8898;
  --frost:#F4F6F9;
  --card:#FFFFFF;
  --steel:#E4E9ED;
  --steel-dash:#C4CDD6;
  --hivis:#E8641B;
  --hivis-dark:#CF5512;
  --hivis-ghost:rgba(232,100,27,.7);
  --hivis-tile-bg:#FEF4EE;
  --coolant:#1F7A8A;
  --ok:#1E9E5A;
  --ok-2:#2ECC80;
  --warn:#C9A227;
  --warn-2:#A07E14;
  --loss:#B23A2E;
  --text-on-dark:#B7C2CE;
  --link-on-dark:#D8E0E8;
  --footer-divider:#24313F;
  --radius-card:10px;
  --radius-img:12px;
  --radius-btn:7px;
  --radius-modal:14px;
  --max-w:1200px;
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--card);
  color:var(--ink);
  font-family:'Archivo',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
}
a{color:var(--hivis)}
a:hover{color:var(--hivis-dark)}
img{max-width:100%}
button{font-family:inherit}

.wrap{max-width:var(--max-w);margin:0 auto;padding-left:32px;padding-right:32px}
@media (max-width:640px){.wrap{padding-left:20px;padding-right:20px}}

.mono{font-family:'IBM Plex Mono',monospace}

/* ---------------------------------------------------------------- nav -- */
.site-nav{background:var(--card);border-bottom:1px solid var(--steel);position:relative;z-index:50}
.site-nav .wrap{
  display:flex;align-items:center;gap:26px;
  min-height:72px;padding-top:12px;padding-bottom:12px;
}
.site-nav .logo{flex:none;display:flex;align-items:center}
.site-nav .logo img{height:34px;display:block}
.site-nav nav{display:flex;align-items:center;justify-content:center;gap:22px;flex:1;flex-wrap:wrap}
.site-nav .navlink{
  text-decoration:none;white-space:nowrap;font:600 13.5px 'Archivo',sans-serif;
  padding:6px 0;border-bottom:2px solid transparent;color:var(--ink-2);
}
.site-nav .navlink:hover,.site-nav .navlink.active{color:var(--ink)}
.site-nav .navlink.active{border-bottom-color:var(--hivis)}
.site-nav .soon{
  font:600 9px 'IBM Plex Mono',monospace;letter-spacing:.1em;color:var(--muted);
  border:1px solid var(--steel);border-radius:4px;padding:2px 5px;text-transform:uppercase;
}
.site-nav .with-soon{display:flex;align-items:center;gap:7px}
.site-nav .product-wrap{position:relative}
.site-nav .product-btn{
  background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:5px;
  font:600 13.5px 'Archivo',sans-serif;padding:6px 0;border-bottom:2px solid transparent;color:var(--ink-2);
}
.site-nav .product-btn:hover,.site-nav .product-wrap.active .product-btn{color:var(--ink)}
.site-nav .product-wrap.active .product-btn{border-bottom-color:var(--hivis)}
.site-nav .product-btn .caret{font-size:9px;position:relative;top:-1px}
.site-nav .product-menu{
  position:absolute;top:100%;left:-14px;padding-top:10px;display:none;
}
.site-nav .product-wrap:hover .product-menu,
.site-nav .product-wrap:focus-within .product-menu{display:block}
.site-nav .product-menu-inner{
  background:var(--card);border:1px solid var(--steel);border-radius:10px;
  box-shadow:0 8px 28px rgba(20,32,46,.12);padding:8px;display:flex;flex-direction:column;min-width:230px;
}
.site-nav .product-menu a{
  text-decoration:none;display:flex;flex-direction:column;gap:2px;padding:10px 14px;border-radius:7px;
}
.site-nav .product-menu a:hover{background:var(--frost)}
.site-nav .product-menu a.active{background:var(--frost)}
.site-nav .product-menu a .t{font:600 14px 'Archivo',sans-serif;color:var(--ink)}
.site-nav .product-menu a .d{font:400 12.5px 'Archivo',sans-serif;color:var(--muted)}

/* Solutions mega-menu (v2) - same open/close mechanism as .product-wrap
   above (hover + focus-within here in CSS, force-open + inline display
   toggle in JS for click/touch - see wireNav()'s solWrap block), just
   wider and split into two labelled groups since it fans out to six
   pages instead of five flat links. */
.site-nav .sol-wrap{position:relative}
.site-nav .sol-btn{
  background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:5px;
  font:600 13.5px 'Archivo',sans-serif;padding:6px 0;border-bottom:2px solid transparent;color:var(--ink-2);
}
.site-nav .sol-btn:hover,.site-nav .sol-wrap.active .sol-btn{color:var(--ink)}
.site-nav .sol-wrap.active .sol-btn{border-bottom-color:var(--hivis)}
.site-nav .sol-btn .caret{font-size:9px;position:relative;top:-1px}
.site-nav .sol-menu{position:absolute;top:100%;left:-14px;padding-top:10px;display:none}
.site-nav .sol-wrap:hover .sol-menu,
.site-nav .sol-wrap:focus-within .sol-menu{display:block}
.site-nav .sol-menu-inner{
  background:var(--card);border:1px solid var(--steel);border-radius:10px;
  box-shadow:0 8px 28px rgba(20,32,46,.12);padding:16px;display:grid;
  grid-template-columns:1fr 1fr;gap:20px;width:600px;
}
/* Defensive width cap beyond the literal source (which assumed a fixed
   1280px preview canvas) - the desktop nav row is visible from 861px up
   (see the @media max-width:860px block below), and a flat 600px popup
   positioned left:-14px of a button that isn't at the far left can run
   past the right edge of the viewport at the narrow end of that range. */
.site-nav .sol-menu-inner{max-width:calc(100vw - 64px)}
.site-nav .sol-group{display:flex;flex-direction:column;gap:2px}
.site-nav .sol-group-label{
  font:600 10.5px 'IBM Plex Mono',monospace;letter-spacing:.14em;color:var(--muted);
  text-transform:uppercase;padding:6px 14px 8px;
}
.site-nav .sol-menu a{text-decoration:none;font:600 13.5px 'Archivo',sans-serif;color:var(--ink);padding:9px 14px;border-radius:7px}
.site-nav .sol-menu a:hover,.site-nav .sol-menu a.active{background:var(--frost)}

.site-nav .right{display:flex;align-items:center;gap:18px;flex:none}
.site-nav .signin{text-decoration:none;font:600 13.5px 'Archivo',sans-serif;color:var(--ink-2)}
.site-nav .signin:hover{color:var(--ink)}

/* Mobile nav - see the "added beyond the literal prototype" comment in
   site.js's renderNav(). Below 860px (matching the internal app's own
   mobile-layout breakpoint) the full link row and "Sign in" hide, a
   hamburger toggle appears, and it opens a simple stacked panel instead -
   the "Book a demo" button stays visible at all widths since it's the
   page's one primary action. */
.mnav-toggle{
  display:none;flex:none;background:none;border:none;cursor:pointer;padding:8px;
  flex-direction:column;justify-content:center;gap:5px;width:36px;height:36px;
}
.mnav-toggle span{display:block;width:100%;height:2px;background:var(--ink);border-radius:1px;transition:transform .15s ease,opacity .15s ease}
.mnav-toggle.open span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.mnav-toggle.open span:nth-child(2){opacity:0}
.mnav-toggle.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
.mnav-panel{display:none;flex-direction:column;gap:2px;padding:8px 20px 20px;border-top:1px solid var(--steel)}
.mnav-panel.open{display:flex}
.mnav-panel .mnav-link{
  text-decoration:none;font:600 15px 'Archivo',sans-serif;color:var(--ink-2);padding:12px 4px;
  border-bottom:1px solid var(--frost);
}
.mnav-panel .mnav-link.active{color:var(--hivis)}
.mnav-panel .soon{margin-left:4px}
/* Group label above the Solutions links in the mobile panel (v2) - mirrors
   .sol-group-label's treatment so the "By where you are" / "By what you
   maintain" grouping survives the collapse to a flat stacked list. */
.mnav-panel .mnav-heading{
  font:600 10.5px 'IBM Plex Mono',monospace;letter-spacing:.14em;color:var(--muted);
  text-transform:uppercase;padding:14px 4px 4px;
}
@media (max-width:860px){
  .site-nav .wrap{flex-wrap:wrap}
  .site-nav nav,.site-nav .signin{display:none}
  .mnav-toggle{display:flex}
  .site-nav .right{gap:10px}
}
.btn-primary{
  font:700 13.5px 'Archivo',sans-serif;color:#FFFFFF;background:var(--hivis);
  padding:10px 18px;border-radius:var(--radius-btn);border:none;cursor:pointer;text-decoration:none;
  display:inline-block;
}
.btn-primary:hover{background:var(--hivis-dark);color:#FFFFFF}
.btn-primary.large{font-size:15px;padding:14px 26px}
/* Disabled state (v2) - the reCAPTCHA-mock checkbox gates both the demo
   and support modals' submit buttons via the native disabled attribute
   (see .captcha-box below), so :disabled is all either button needs. */
.btn-primary:disabled,.btn-primary:disabled:hover{background:var(--steel-dash);color:#FFFFFF;cursor:not-allowed}
.btn-ghost-dark{
  font:700 15px 'Archivo',sans-serif;color:#FFFFFF;border:2px solid var(--ink-2);
  padding:12px 24px;border-radius:var(--radius-btn);text-decoration:none;display:inline-block;
}
.btn-ghost-dark:hover{border-color:#E8ECEF;color:#FFFFFF}
.btn-ghost-light{
  font:700 15px 'Archivo',sans-serif;color:var(--ink);border:2px solid var(--ink);
  padding:12px 24px;border-radius:var(--radius-btn);text-decoration:none;display:inline-block;
}
.btn-ghost-light:hover{background:var(--ink);color:#FFFFFF}

/* -------------------------------------------------------------- modal -- */
.modal-overlay{
  position:fixed;inset:0;background:rgba(20,32,46,.6);z-index:300;
  display:none;align-items:flex-start;justify-content:center;padding:48px 24px;
  overflow:auto;box-sizing:border-box;
}
.modal-overlay.open{display:flex}
.modal-card{
  background:var(--card);border-radius:var(--radius-modal);max-width:620px;width:100%;
  padding:36px 40px;position:relative;display:flex;flex-direction:column;gap:18px;
  box-shadow:0 24px 64px rgba(20,32,46,.35);box-sizing:border-box;
}
.modal-close{
  position:absolute;top:14px;right:14px;width:34px;height:34px;border:none;background:var(--frost);
  border-radius:8px;cursor:pointer;font:600 15px 'Archivo',sans-serif;color:var(--ink-2);
}
.modal-close:hover{background:var(--steel)}
.modal-eyebrow{font:600 11.5px 'IBM Plex Mono',monospace;letter-spacing:.16em;color:var(--hivis);text-transform:uppercase}
.modal-title{margin:0;font:800 26px/1.15 'Archivo',sans-serif;letter-spacing:-.015em;color:var(--ink)}
.modal-sub{margin:0;font:400 13px/1.5 'Archivo',sans-serif;color:var(--muted)}
.modal-grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
/* Contact's own two-column layout (form + side notes) - was an inline
   style with no responsive collapse, which overflowed the viewport
   horizontally on a phone (found reviewing a mobile screenshot; the
   modal's own version of this problem is avoided by its max-width:620px
   card, but Contact's full-bleed page layout had no such limit). */
.contact-grid{display:grid;grid-template-columns:1.2fr 1fr;gap:64px;align-items:start}
/* General two-column utility for About/Pricing/Getting-started's simpler
   layouts, which had the exact same bare-inline-grid problem (found the
   same way, reviewing mobile screenshots) - no responsive collapse at
   all. Ratio/gap are set per-page via CSS custom properties on the
   element itself (e.g. style="--tc-ratio:1.3fr 1fr;--tc-gap:64px")
   rather than grid-template-columns directly, so the actual property
   lives in THIS class rule and the media query below can still override
   it - an inline grid-template-columns would out-specificity any class
   media query and silently defeat the collapse, which is exactly the bug
   this whole comment block exists to avoid repeating. */
.two-col{display:grid;grid-template-columns:var(--tc-ratio,1fr 1fr);gap:var(--tc-gap,48px);align-items:start}
@media (max-width:760px){
  .contact-grid,.two-col{grid-template-columns:1fr}
  .modal-grid2{grid-template-columns:1fr}
}
.field{display:flex;flex-direction:column;gap:7px}
.field.span2{grid-column:1 / -1}
.field label,.field .flabel{font:600 12.5px 'Archivo',sans-serif;color:var(--ink-2)}
.field input,.field textarea{
  font:400 15px 'Archivo',sans-serif;color:var(--ink);padding:11px 13px;
  border:1px solid var(--steel-dash);border-radius:var(--radius-btn);background:var(--card);
}
.field textarea{resize:vertical;line-height:1.5}
.field input:focus,.field textarea:focus{border-color:var(--hivis);outline:none}
/* Support modal's "which part of TOWR" dropdown (v2) - .field previously
   only ever wrapped an input or textarea; select needs the same look. */
.field select{
  font:400 15px 'Archivo',sans-serif;color:var(--ink);padding:11px 13px;
  border:1px solid var(--steel-dash);border-radius:var(--radius-btn);background:var(--card);cursor:pointer;
}
.field select:focus{border-color:var(--hivis);outline:none}
.checks{display:flex;gap:18px;flex-wrap:wrap}
.checks label{display:flex;align-items:center;gap:8px;font:400 14.5px 'Archivo',sans-serif;color:var(--ink);cursor:pointer}
.checks input{width:16px;height:16px;accent-color:var(--hivis);cursor:pointer}
/* Support's urgency group reuses .checks/.checks label/.checks input
   as-is with type="radio" instead of "checkbox" - same look, no new
   class needed, since the CSS never actually names an input type. */
.modal-sent-eyebrow{font:600 12px 'IBM Plex Mono',monospace;letter-spacing:.16em;color:var(--ok);text-transform:uppercase}
.modal-sent-title{margin:0;font:800 24px/1.15 'Archivo',sans-serif;color:var(--ink)}

/* reCAPTCHA-style mock (v2) - gates the demo AND support modals' submit
   buttons. This is NOT a real Google reCAPTCHA integration: no site key
   exists yet (open question tracked elsewhere, PEM-611), so this is
   deliberately just a plain checkbox styled to look like the widget,
   exactly matching the approved design source. Ungates the submit button
   (see .btn-primary:disabled above) the moment it's checked and nothing
   more - there is no bot-detection logic to port because the source
   doesn't have any either. */
.captcha-box{
  width:100%;max-width:302px;margin-left:auto;box-sizing:border-box;
  background:#F9F9F9;border:1px solid #D3D3D3;border-radius:3px;padding:11px 12px;
  display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
}
.captcha-box .check{display:flex;align-items:center;gap:12px;cursor:pointer;font:400 14px 'Archivo',sans-serif;color:var(--ink)}
.captcha-box .check input{width:22px;height:22px;accent-color:var(--ok);cursor:pointer}
.captcha-box .badge{display:flex;flex-direction:column;align-items:center;gap:1px}
.captcha-box .badge .name{font:500 10px 'Archivo',sans-serif;color:var(--muted)}
/* One-off lighter grey below --muted, matching the source's own badge
   sub-caption exactly (its "Privacy / Terms" line is a shade lighter
   than the "reCAPTCHA" line above it) - not worth a new root token for
   a single decorative line inside a mock badge. */
.captcha-box .badge .legal{font:400 8px 'Archivo',sans-serif;color:#9AA6B2}

/* -------------------------------------------------------------- hero --- */
.hero{padding:96px 32px 84px;display:flex;flex-direction:column;align-items:center;text-align:center;gap:22px}
.hero-dark{background:var(--ink)}
.hero-light{background:var(--frost)}
.hero-eyebrow{font:600 12px 'IBM Plex Mono',monospace;letter-spacing:.18em;color:var(--hivis);text-transform:uppercase}
.hero-dark h1{color:#FFFFFF}
.hero-light h1{color:var(--ink)}
.hero h1{margin:0;font:800 56px/1.05 'Archivo',sans-serif;letter-spacing:-.02em;max-width:760px;text-wrap:balance}
.hero-dark p{color:var(--text-on-dark)}
.hero-light p{color:var(--ink-2)}
.hero p{margin:0;font:400 19px/1.55 'Archivo',sans-serif;max-width:640px;text-wrap:pretty}
.hero .ctas{display:flex;gap:14px;margin-top:10px;flex-wrap:wrap;justify-content:center}
@media (max-width:640px){.hero h1{font-size:38px}.hero p{font-size:17px}}

/* ------------------------------------------------------------ ghost --- */
.ghost-heading{
  font:600 clamp(40px,4.5vw,72px)/1.15 'IBM Plex Mono',monospace;
  letter-spacing:.06em;color:var(--hivis-ghost);text-transform:uppercase;white-space:nowrap;
  overflow:hidden;max-width:100%;margin:0 0 -0.45em -4px;pointer-events:none;user-select:none;
}
/* PEM's ghost-heading is the one long string on the whole site ("PEM —
   Planning & Execution Manager", 35 chars vs. "THE WAREHOUSE" at 13) - at
   the default clamp it clips mid-word at ordinary desktop widths. This is
   a real bug in the approved source design itself (confirmed byte-for-byte
   identical to PEM.dc.html - Claude Design's own preview canvas never hit
   this width/font combination), not a translation error, so fixed with a
   size-only modifier that changes nothing else about the ghost-heading
   treatment or any page's copy. */
.ghost-heading.long{font-size:clamp(24px,3.2vw,52px)}
/* Below ~600px even the reduced size clips mid-word - this element is
   aria-hidden and pointer-events:none (purely decorative texture, the
   source design's own markup, not information), so hiding it loses
   nothing a phone visitor could read; the real H1 right next to it
   already says what the page is about. */
@media (max-width:600px){.ghost-heading.long{display:none}}
/* The same clipping risk exists, more mildly, for every OTHER
   ghost-heading too: the clamp's 40px floor is fixed regardless of how
   narrow the viewport gets, so between ~600-889px width it doesn't shrink
   at all even though the available space keeps shrinking. "Contact / Book
   a demo" (21 chars, contact.html) is the next-longest after PEM's and
   would clip under the unmodified 40px floor at a phone width; shorter
   ones ("The Warehouse", "Smart Upload" etc.) have enough margin not to,
   but there's no reason to leave them at a size this method didn't
   actually verify fits. One safe, conservative floor for every
   non-.long ghost-heading below 600px, sized to comfortably fit the
   longest of the ordinary (non-PEM) strings. */
@media (max-width:600px){
  .ghost-heading:not(.long){font-size:22px}
}

/* --------------------------------------------------------- sections --- */
.section{padding:80px 32px 84px}
.section-tight{padding:72px 32px}
.section-eyebrow{font:600 12px 'IBM Plex Mono',monospace;letter-spacing:.16em;color:var(--muted);text-transform:uppercase}
.section h2{margin:0;font:800 34px/1.1 'Archivo',sans-serif;letter-spacing:-.015em}
.section-frost{background:var(--frost)}
.section-white{background:var(--card)}
.section-ink{background:var(--ink)}
.section-ink h2{color:#FFFFFF}
.section-ink p{color:var(--text-on-dark)}

.cards-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:24px}
.card{
  display:flex;flex-direction:column;gap:12px;text-decoration:none;background:var(--card);
  border:1px solid var(--steel);border-left:4px solid var(--hivis);border-radius:var(--radius-card);
  padding:26px 26px 24px;min-height:150px;
}
.card:hover{border-color:var(--steel-dash);box-shadow:0 2px 10px rgba(20,32,46,.07)}
/* .card used as a plain info panel, not a link (The Books' status cards -
   no href/hover in the source design). Keeps the left-accent-per-card
   language without inventing a hover affordance for something unclickable. */
.card.static:hover{border-color:var(--steel);box-shadow:none}
.card h3{margin:0;font:800 19px/1.2 'Archivo',sans-serif;color:var(--ink)}
.card .sub{font:600 12px 'Archivo',sans-serif;color:var(--muted);margin-top:-6px;display:block}
.card p{margin:0;font:400 14.5px/1.55 'Archivo',sans-serif;color:var(--ink-2);text-wrap:pretty}
.card .cta{font:600 12px 'IBM Plex Mono',monospace;letter-spacing:.1em;color:var(--hivis);text-transform:uppercase;margin-top:auto}
/* Colored uppercase status tag (The Books' Blocked / Drifted / Doesn't add
   up) - a second label style alongside .sub, since these read as a status
   callout coloured to match the card's border rather than a muted
   subheading. Color is set per instance the same way per-card
   border-left-color already is (see Home's / The Books' cards). */
.card .tag{font:600 11.5px 'IBM Plex Mono',monospace;letter-spacing:.12em;text-transform:uppercase;display:block}

/* Card variant: top-border accent instead of left, plus a small mono index
   number above the heading. Used for The Warehouse's numbered "starting
   point" cards (01/02/03) - these are plain info panels (no link, no
   hover), and use a different accent side than the left-border
   product/status cards above, so it's its own modifier rather than
   overloading .card. */
.card-top{
  display:flex;flex-direction:column;gap:12px;background:var(--card);
  border:1px solid var(--steel);border-top:4px solid var(--hivis);border-radius:var(--radius-card);
  padding:26px;
}
.card-top .num{font:600 12px 'IBM Plex Mono',monospace;letter-spacing:.14em;color:var(--muted)}
.card-top h3{margin:0;font:800 18px/1.25 'Archivo',sans-serif}
.card-top p{margin:0;font:400 14.5px/1.55 'Archivo',sans-serif;color:var(--ink-2);text-wrap:pretty}
/* Solutions pages' (Commercial Refrigeration, HVAC, Facilities) "pain /
   TOWR's answer" cards - same top-accent shape as .card-top's 01/02/03
   panels above, but with two small labelled rows either side of a divider
   and a .link-arrow footer pointing at the relevant product page. Its own
   modifier rather than changing .card-top itself, since Warehouse's own
   01/02/03 cards have no internal labels/divider and stay exactly as they
   are. */
.card-top .eyebrow-mini{font:600 10.5px 'IBM Plex Mono',monospace;letter-spacing:.14em;color:var(--muted);text-transform:uppercase}
.card-top .eyebrow-mini.accent{color:var(--hivis)}
.card-top .divider{height:1px;background:#F0F2F5;margin:4px 0}
.card-top .link-arrow{margin-top:auto}

/* Standalone full-width image (not inside .split) - the same border+radius
   treatment .split img already uses, factored out for images that sit on
   their own between sections (Warehouse's before/after photo etc). */
.img-block{width:100%;height:auto;border-radius:var(--radius-img);border:1px solid var(--steel);display:block}

.split{display:grid;grid-template-columns:1fr 1.6fr;gap:48px;align-items:center}
.split.reverse{grid-template-columns:1.6fr 1fr}
/* Warehouse (Smart Upload) and PEM (the board image) both want a closer-
   to-even column ratio than the default 1:1.6 - these used to be inline
   `style="grid-template-columns:..."` overrides, which (found reviewing a
   mobile screenshot) defeated the collapse rule below: an inline style
   attribute beats any class selector's specificity, media query or not,
   so the "responsive" .split was silently staying two columns at a phone
   width and squeezing both the image and every line of body text into
   ~150px. Real classes here means the SAME collapse rule below can target
   them explicitly instead of losing the specificity fight. */
.split.ratio-close{grid-template-columns:1.05fr 1fr}
.split.reverse.ratio-close{grid-template-columns:1fr 1.1fr}
.split .copy{display:flex;flex-direction:column;gap:16px}
.split h2{text-wrap:balance}
.split p{margin:0;font:400 16px/1.6 'Archivo',sans-serif;color:var(--ink-2);text-wrap:pretty}
.split img{width:100%;height:auto;border-radius:var(--radius-img);border:1px solid var(--steel);display:block}
.link-arrow{font:600 13px 'IBM Plex Mono',monospace;letter-spacing:.08em;color:var(--hivis);text-decoration:none;text-transform:uppercase}
.link-arrow:hover{color:var(--hivis-dark)}
@media (max-width:860px){
  .split,.split.reverse,.split.ratio-close,.split.reverse.ratio-close{grid-template-columns:1fr}
}

.cta-band{
  background:var(--ink);clip-path:polygon(0 0,calc(100% - 40px) 0,100% 40px,100% 100%,0 100%);
  padding:64px 48px;display:flex;flex-direction:column;align-items:center;text-align:center;gap:18px;
}
.cta-band h2{color:#FFFFFF}
.cta-band p{margin:0;font:400 16px/1.55 'Archivo',sans-serif;color:var(--text-on-dark);max-width:520px;text-wrap:pretty}
.cta-band .ctas{display:flex;gap:14px;margin-top:8px;flex-wrap:wrap;justify-content:center}
/* Light/frost cta-band variant - The Warehouse and PEM's closing bands use
   the frost surface rather than ink (Home's and The Books' use the default
   dark band above). Chamfer, padding and layout are identical; only the
   two surface colors flip. */
.cta-band.light{background:var(--frost)}
.cta-band.light h2{color:var(--ink)}
.cta-band.light p{color:var(--ink-2)}

/* --------------------------------------------------------- footer ----- */
.site-footer{background:var(--ink);color:var(--text-on-dark)}
/* Five columns since the Solutions column was added: brand · Product ·
   Solutions · Company · See it running. Solutions gets the widest of the
   link columns because its labels are the longest on the site
   ("Commercial Refrigeration & Catering", 35 chars); at 1fr they wrapped
   to two lines each and the column read as twelve items rather than six. */
.site-footer .grid{
  display:grid;grid-template-columns:1.3fr 0.9fr 1.4fr 0.9fr 1.1fr;gap:36px;
  padding:56px 32px 40px;
}
.site-footer .col{display:flex;flex-direction:column;gap:10px}
.site-footer .brand-col{gap:16px}
.site-footer .brand-col img{height:32px;width:auto;align-self:flex-start}
.site-footer .brand-col p{margin:0;font:400 14px/1.55 'Archivo',sans-serif;max-width:280px}
.site-footer .heading{font:600 11px 'IBM Plex Mono',monospace;letter-spacing:.14em;color:var(--muted);text-transform:uppercase;margin-bottom:4px}
.site-footer a{text-decoration:none;font:500 14px 'Archivo',sans-serif;color:var(--link-on-dark)}
.site-footer a:hover{color:#FFFFFF}
.site-footer .see-it{gap:14px;align-items:flex-start}
.site-footer .see-it p{margin:0;font:400 14px/1.55 'Archivo',sans-serif}
.site-footer .see-it .btn-primary{font-size:13.5px;padding:11px 20px}
.site-footer .bottom{border-top:1px solid var(--footer-divider)}
.site-footer .footnote{max-width:var(--max-w);margin:0 auto;padding:16px 32px 0;font:400 12px/1.5 'Archivo',sans-serif;color:var(--muted)}
.site-footer .legal{
  max-width:var(--max-w);margin:0 auto;padding:12px 32px 18px;display:flex;
  justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;
}
.site-footer .copyright{font:400 12.5px 'Archivo',sans-serif;color:var(--muted)}
.site-footer .taglinemark{font:500 11px 'IBM Plex Mono',monospace;letter-spacing:.12em;color:var(--muted);text-transform:uppercase}
@media (max-width:860px){.site-footer .grid{grid-template-columns:1fr 1fr;gap:32px}}
@media (max-width:520px){.site-footer .grid{grid-template-columns:1fr}}

/* ------------------------------------------------------- subpage hero -- */
/* The dark, left-aligned hero used on every page below Home — Reporting,
   Integrations, Getting started, and (by the same .dc.html pattern) the
   product pages not yet built. Distinct from Home's centred .hero-dark:
   left-aligned copy, the ghost-heading as the section label instead of
   the small mono eyebrow, and a fixed 1200px content width. Shared here
   because all three source design files use this exact structure. */
.subhero{background:var(--ink);padding:80px 32px 64px}
.subhero .inner{max-width:var(--max-w);margin:0 auto;display:flex;flex-direction:column;gap:20px}
.subhero h1{margin:0;font:800 48px/1.08 'Archivo',sans-serif;letter-spacing:-.02em;color:#FFFFFF;max-width:820px;text-wrap:balance}
.subhero p{margin:0;font:400 18px/1.55 'Archivo',sans-serif;color:var(--text-on-dark);max-width:660px;text-wrap:pretty}
.subhero .ctas{display:flex;gap:14px;margin-top:6px;flex-wrap:wrap}

/* ---------------------------------------------------------- step list -- */
/* A short vertical list of "index + line" rows — the orange arrows on
   Reporting, the 01/02/03 steps on Getting started. Same shape, two
   different marks, so the mark itself is just text content, not a class. */
.step-list{display:flex;flex-direction:column;gap:10px;margin-top:4px}
.step-list .row{display:flex;gap:12px;align-items:baseline}
.step-list .mark{font:600 12px 'IBM Plex Mono',monospace;color:var(--hivis)}
.step-list .row>span:last-child{font:500 15px/1.5 'Archivo',sans-serif;color:var(--ink)}

/* ---------------------------------------------------- integration tiles -- */
/* Integrations page only: one filled "live" tile, any number of dashed
   "on the roadmap" tiles, and one accent tile that opens the demo modal.
   Kept here rather than inline since it's three variants of one shape. */
.tiles-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:20px}
.tile{display:flex;flex-direction:column;gap:8px;border-radius:var(--radius-card);padding:22px 24px}
.tile-live{background:var(--ink)}
.tile-live .status{display:flex;align-items:center;gap:8px}
.tile-live .dot{width:8px;height:8px;border-radius:50%;background:var(--ok-2)}
.tile-live .label{font:600 11px 'IBM Plex Mono',monospace;letter-spacing:.14em;color:var(--ok-2);text-transform:uppercase}
.tile-live .name{font:800 20px 'Archivo',sans-serif;color:#FFFFFF}
.tile-live p{margin:0;font:400 13.5px/1.5 'Archivo',sans-serif;color:var(--text-on-dark)}
.tile-roadmap{border:1px dashed var(--steel-dash)}
.tile-roadmap .label{font:600 11px 'IBM Plex Mono',monospace;letter-spacing:.14em;color:var(--muted);text-transform:uppercase}
.tile-roadmap .name{font:800 20px 'Archivo',sans-serif;color:var(--ink-2)}
.tile-accent{border:1px solid var(--hivis);background:var(--hivis-tile-bg)}
.tile-accent .label{font:600 11px 'IBM Plex Mono',monospace;letter-spacing:.14em;color:var(--hivis);text-transform:uppercase}
.tile-accent p{margin:0;font:400 13.5px/1.5 'Archivo',sans-serif;color:var(--ink-2)}
.tile-accent a{color:var(--hivis);font-weight:600;cursor:pointer}

/* ---------------------------------------------------------- plain card -- */
/* A plain bordered content box with no left accent and no link/hover
   behaviour — used for the "do it yourself / need more" pair on Getting
   started. Distinct from .card, which is always a clickable feature tile
   with an accent border and a hover state. */
.plain-card{background:var(--card);border:1px solid var(--steel);border-radius:var(--radius-card);padding:28px;display:flex;flex-direction:column;gap:12px}
.plain-card h3{margin:0;font:800 19px 'Archivo',sans-serif;color:var(--ink)}
.plain-card p{margin:0;font:400 15px/1.6 'Archivo',sans-serif;color:var(--ink-2);text-wrap:pretty}

/* dark-surface note: this site is light-first by design (the marketing
   brief specifies exact light/dark surfaces per SECTION, e.g. dark hero,
   dark CTA band, dark footer) rather than a whole-page theme toggle like
   the internal app has - so there is no prefers-color-scheme override
   here on purpose; every section's colour is deliberate, not a mode. */
