/* ============================================================================
   SILVERA MOBILITY

   Two constraints pull against each other here and both hold: do not design it
   like a hospital supply catalogue, and do not reduce clarity to look
   luxurious. Everything premium in this file is bought with typography,
   restraint and space. Nothing is bought by shrinking type, dropping contrast
   or hiding navigation, because the customer may have reduced vision, reduced
   hand control or a bad connection, and accessibility here is the product
   rather than a checklist appended to it.

   1  tokens
   2  reset and base
   3  typography
   4  layout
   5  buttons and controls
   6  header, mega menu, mobile nav
   7  hero
   8  needs, products, cards
   9  product page
   10 comparison
   11 finder
   12 editorial, guides, policy
   13 footer
   14 line art
   15 responsive
   ========================================================================= */

/* ---------------------------------------------------------------- 1 tokens */
:root {
  --paper:      #FCFBF9;   /* warm white, never clinical */
  --paper-2:    #F4F2EE;   /* the quiet band */
  --paper-3:    #EAE7E1;
  --ink:        #14181C;   /* graphite, deliberately not navy: navy is Digilu */
  --ink-2:      #3A4247;
  --silver:     #6E777C;   /* 5.1:1 on paper. the lightest text tone allowed */
  --hair:       #DCD8D1;

  --sig:        #E0701A;   /* marigold. graphic use only */
  --sig-ink:    #96490B;   /* 6.4:1 on paper. every accent TEXT uses this */
  --sig-tint:   #FBF0E5;
  --sig-hair:   #EFD3B4;

  --ok:         #2C6E49;
  --warn-ink:   #8A5A00;

  --display: 'Jost', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --body: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Body copy is 18px on desktop and never below 16px anywhere. This is not a
     concession to the audience, it is what makes long product copy readable. */
  --fs-body: 1.125rem;
  --lh-body: 1.65;

  --shell: 1240px;
  --gut: 2rem;
  --rad: 4px;      /* almost square. rounded-rectangle soup is the thing to avoid */
  --focus: 3px solid var(--sig-ink);
}

/* ------------------------------------------------------- 2 reset and base */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;         /* the page body must never scroll sideways */
}

img, svg, video { max-width: 100%; }
img { height: auto; display: block; }   /* height:auto or a height attr stretches it */

a { color: inherit; }

:focus-visible {
  outline: var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--ink); color: #fff; padding: 1rem 1.5rem;
  font-weight: 600; text-decoration: none;
}
.skip:focus { left: 0; }

.sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------- 3 typography */
/* An inline SVG with no width attribute fills its container, which turns a 22px
   tick in a heading into a 500px one. Constrain it once, here, rather than
   remembering to size every icon at every call site. */
h4 > svg, h4 svg, .tickset > li > svg, .trustline svg, .pdp-reassure svg {
  width: 22px; height: 22px; flex: 0 0 22px;
}
h4 { display: flex; align-items: center; gap: .55rem; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.015em;
  margin: 0 0 .6em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.6rem, 6vw, 4.4rem); letter-spacing: -0.028em; }
h2 { font-size: clamp(2rem, 4vw, 2.9rem); letter-spacing: -0.022em; }
h3 { font-size: clamp(1.35rem, 2.2vw, 1.65rem); }
h4 { font-size: 1.18rem; }

p { margin: 0 0 1.15em; max-width: 68ch; }

.eyebrow {
  font-family: var(--display);
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--sig-ink);
  margin: 0 0 1.1rem;
}
.eyebrow--quiet { color: var(--silver); }

.lede {
  font-size: clamp(1.2rem, 1.9vw, 1.4rem);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 60ch;
}

.fine { font-size: .95rem; color: var(--silver); line-height: 1.55; }

/* ------------------------------------------------------------- 4 layout */
.shell { max-width: var(--shell); margin: 0 auto; padding: 0 var(--gut); }
.shell--narrow { max-width: 820px; }

section { padding: clamp(3rem, 5.5vw, 5rem) 0; }
section.tight { padding: clamp(2rem, 3.5vw, 3rem) 0; }
.band { background: var(--paper-2); }
.band--ink { background: var(--ink); color: var(--paper); }
.band--ink .lede, .band--ink .fine { color: #B9BFC3; }
.band--ink .eyebrow { color: var(--sig); }
.band--sig { background: var(--sig-tint); }

.rule { border: 0; border-top: 1px solid var(--hair); margin: 0; }

.section-head { margin-bottom: clamp(1.5rem, 2.6vw, 2.4rem); max-width: 40ch; }
.section-head p { color: var(--ink-2); }

.grid { display: grid; gap: clamp(1.5rem, 3vw, 2.6rem); }
.g-2 { grid-template-columns: repeat(2, 1fr); }
.g-3 { grid-template-columns: repeat(3, 1fr); }
.g-4 { grid-template-columns: repeat(4, 1fr); }

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

/* ------------------------------------------------ 5 buttons and controls */
/* 52px minimum height everywhere. A person with reduced hand control does not
   get a second chance at a 36px target. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  min-height: 54px; padding: .85rem 1.9rem;
  font-family: var(--display); font-size: 1.05rem; font-weight: 500;
  letter-spacing: .01em;
  border: 2px solid transparent; border-radius: var(--rad);
  text-decoration: none; cursor: pointer;
  transition: background-color .16s ease, border-color .16s ease, color .16s ease;
}
.btn--primary { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn--primary:hover { background: #000; border-color: #000; }
.btn--sig { background: var(--sig-ink); color: #fff; border-color: var(--sig-ink); }
.btn--sig:hover { background: #7C3C08; border-color: #7C3C08; }
.btn--ghost { border-color: var(--ink); color: var(--ink); background: transparent; }
.btn--ghost:hover { background: var(--ink); color: var(--paper); }
.band--ink .btn--ghost { border-color: var(--paper); color: var(--paper); }
.band--ink .btn--ghost:hover { background: var(--paper); color: var(--ink); }
.btn--wide { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }

.textlink {
  font-weight: 500; color: var(--sig-ink);
  text-decoration: underline; text-underline-offset: .25em;
  text-decoration-thickness: 1.5px;
}
.textlink:hover { text-decoration-thickness: 2.5px; }

/* --------------------------------------- 6 header, mega menu, mobile nav */
.site-header {
  position: sticky; top: 0; z-index: 200;
  background: var(--paper);
  border-bottom: 1px solid var(--hair);
}
.header-inner {
  max-width: var(--shell); margin: 0 auto; padding: 0 var(--gut);
  display: flex; align-items: center; gap: 2rem; min-height: 72px;
}
.site-logo { display: flex; align-items: center; flex: 0 0 auto; }
.site-logo img { height: 40px; width: auto; }

.primary-nav { display: flex; align-items: center; gap: .25rem; margin-left: auto; }
.nav-item { position: relative; }
.nav-link {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: 1.1rem .95rem; min-height: 54px;
  font-family: var(--display); font-size: 1.02rem; font-weight: 500;
  text-decoration: none; color: var(--ink);
  border-bottom: 3px solid transparent;
}
.nav-item:hover > .nav-link,
.nav-item:focus-within > .nav-link { border-bottom-color: var(--sig); }
.nav-caret { width: 15px; height: 15px; opacity: .5; transition: transform .18s ease; }
.nav-item:hover .nav-caret, .nav-item:focus-within .nav-caret { transform: rotate(180deg); }

.mega-menu {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%) translateY(-8px);
  min-width: 640px;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
  padding-top: 10px;
}
.mega-menu--wide { min-width: 880px; }
/* The --r right-anchored variant is GONE, not overridden. It is what put "About
   Silvera" 246px off centre, and a variant that opts out of the placement rule
   cannot be reconciled with it: the placement kit centres everything and its
   clamp decides how far a panel near the edge may slide. The class survives in
   the markup as a no-op (see the MEGAMENU-PLACEMENT block). */
.nav-item:hover > .mega-menu,
.nav-item:focus-within > .mega-menu {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

/* Spacing, measured not guessed (2026-07-30). At 2rem of padding and .7rem per
   row this panel measured 46% air per row on "Wheelchairs", the airiest column in
   the whole ecosystem, and "Mobility Guides" reached 666px and ran 32.78px PAST
   THE FOLD at 1280x720. The approved fleet sits at 25-35% air on 220-430px cards.
   Tightening the row padding and the panel padding takes ~130px out of the tallest
   panel, which is what actually clears the fold: the fold guard in the placement
   kit would only have clipped it. Tight, not crowded: see the DENSITY rule in
   ecosystem-site-engine/modules/megamenu/core/contract.mjs. */
.mega-menu-inner {
  background: var(--paper);
  border: 1px solid var(--hair);
  border-top: 3px solid var(--sig);
  box-shadow: 0 22px 50px rgba(20, 24, 28, .13);
  padding: 1.5rem;
  display: grid; gap: 1.5rem;
}
.mega-menu--wide .mega-menu-inner { grid-template-columns: 1.15fr 1fr; }

.mm-glabel {
  display: block; font-family: var(--display); font-size: .74rem; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: var(--silver);
  margin: 0 0 .9rem;
}
.mm-list { display: grid; gap: .1rem; align-content: start; }
.mm-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1.6rem; }

/* Two columns for a long list. "Mobility Guides" reached 8 rows and 666px stacked,
   which ran 32.78px PAST THE FOLD at 1280x720 and still landed 75% down the hero
   after the row padding was tightened. Re-flowing beats trimming: dropping a guide
   to make the panel fit would solve the measurement instead of the problem, and it
   is the same call the July pass made on aiotruth and aioinsights.
   column-count and not grid, because the section label has to span both columns and
   `column-span: all` does that without giving the label its own grid cell beside a
   row. display:block is required: column-count does not apply to a grid container. */
.mm-list--cols {
  display: block;
  min-width: 720px;
  column-count: 2;
  column-gap: 1.6rem;
}
.mm-list--cols .mm-glabel { column-span: all; }
.mm-list--cols .mm-row { break-inside: avoid; }

/* THREE columns, because two stopped being enough. The note above fixed
   "Mobility Guides" at 8 rows. It is 17 now, and on 2026-08-08 it measured
   770x876 and ended 230px PAST THE FOLD at 1280x720: the worst mega-menu in
   the fleet. Re-flowing again beats dropping a guide, for the same reason
   given above. A list that outgrows three columns is a sign the section needs
   splitting, not a fourth column. */
.mm-list--cols3 { column-count: 3; min-width: 1020px; }

/* A row description is a description, not a paragraph. Three of these guides
   carry 100+ character sentences ("Usually only if its battery is under 300Wh
   and it folds small enough, and even then the airline can still refuse it"),
   and a single row wrapping to five lines is half the reason this panel grew.
   The full sentence still lives on the page the row links to, which is where
   somebody deciding it can actually read it. */
.mega-menu .mm-ds {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.mm-row {
  display: flex; gap: .85rem; align-items: flex-start;
  padding: .45rem .75rem; margin: 0 -.75rem;
  text-decoration: none; border-radius: var(--rad);
}
.mm-row:hover { background: var(--paper-2); }
.mm-ico { flex: 0 0 26px; margin-top: 2px; }
.mm-ico svg { width: 26px; height: 26px; display: block; }
.mm-tt { display: block; font-family: var(--display); font-weight: 500; font-size: 1.02rem; }
.mm-ds { display: block; font-size: .88rem; color: var(--silver); line-height: 1.4; margin-top: .1rem; }

.mm-feature {
  background: var(--paper-2); padding: 1.6rem; border-radius: var(--rad);
  display: flex; flex-direction: column;
}
.mm-feature img { border-radius: var(--rad); margin-bottom: 1.1rem; }
.mm-feature .mm-tt { font-size: 1.15rem; margin-bottom: .3rem; }

.header-cta { display: flex; align-items: center; gap: .8rem; flex: 0 0 auto; }
.header-cta .btn { min-height: 48px; padding: .6rem 1.3rem; font-size: .98rem; }

.menu-toggle {
  display: none; width: 54px; height: 54px; background: none;
  border: 1px solid var(--hair); border-radius: var(--rad); cursor: pointer;
  padding: 0; position: relative;
}
.menu-toggle span {
  display: block; width: 24px; height: 2px; background: var(--ink);
  margin: 5px auto; transition: transform .2s ease, opacity .2s ease;
}
.menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.mobile-nav {
  display: none; background: var(--paper); border-bottom: 1px solid var(--hair);
  padding: 1rem var(--gut) 2rem;
  max-height: calc(100vh - 84px); overflow-y: auto;
}
.mobile-nav.open { display: block; }
.mobile-nav a {
  display: block; padding: 1rem 0; min-height: 54px;
  font-family: var(--display); font-size: 1.15rem; text-decoration: none;
  border-bottom: 1px solid var(--hair);
}
.mnav-group > summary {
  list-style: none; cursor: pointer; padding: 1rem 0; min-height: 54px;
  font-family: var(--display); font-size: 1.15rem;
  border-bottom: 1px solid var(--hair);
  display: flex; justify-content: space-between; align-items: center;
}
.mnav-group > summary::-webkit-details-marker { display: none; }
.mnav-group > summary::after { content: '+'; font-size: 1.5rem; color: var(--silver); }
.mnav-group[open] > summary::after { content: '\2212'; }
.mnav-group a { padding-left: 1rem; font-size: 1.02rem; color: var(--ink-2); }
.mobile-cta { margin-top: 1.5rem; display: grid; gap: .8rem; }

/* --------------------------------------------------------------- 7 hero */
.hero { padding: 0; border-bottom: 1px solid var(--hair); }
.hero-inner {
  max-width: var(--shell); margin: 0 auto; padding: clamp(3rem, 6vw, 5.5rem) var(--gut);
  display: grid; grid-template-columns: 1.02fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
}
.hero h1 { margin-bottom: 1.2rem; }
.hero .lede { margin-bottom: 2rem; }
.hero-media { position: relative; }
.hero-media img { border-radius: var(--rad); width: 100%; }

/* A caption instead of text laid over the photograph. Text on an image is a
   contrast failure waiting for the next breakpoint. */
.hero-cap {
  margin-top: .9rem; font-size: .92rem; color: var(--silver);
  display: flex; gap: .6rem; align-items: baseline;
}
.hero-cap b { color: var(--ink); font-weight: 600; }

.trustline {
  display: flex; flex-wrap: wrap; gap: 1.5rem 2.2rem;
  padding: 1.4rem 0 0; margin-top: 2rem; border-top: 1px solid var(--hair);
  font-size: .96rem; color: var(--ink-2);
}
.trustline span { display: flex; gap: .5rem; align-items: center; }
.trustline svg { width: 20px; height: 20px; flex: 0 0 20px; }

/* --------------------------------------------- 8 needs, products, cards */
.need-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; border-top: 1px solid var(--hair); }
.need {
  display: flex; flex-direction: column; gap: .8rem;
  padding: 2rem 1.8rem 2.2rem;
  border-right: 1px solid var(--hair); border-bottom: 1px solid var(--hair);
  text-decoration: none; background: transparent;
  transition: background-color .16s ease;
}
.need:first-child { border-left: 1px solid var(--hair); }
.need:hover { background: var(--paper-2); }
.need__mark svg { width: 46px; height: 46px; }
.need__q { font-family: var(--display); font-size: 1.22rem; line-height: 1.25; }
.need__blurb { font-size: .96rem; color: var(--silver); margin: 0; }
.need__go { margin-top: auto; padding-top: .8rem; font-size: .93rem; font-weight: 600; color: var(--sig-ink); }

/* Product tiles are a grid, not floating rounded rectangles. The separation is
   done with alignment and one hairline. */
.prod-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.5rem, 3vw, 2.6rem); }
.prod {
  display: flex; flex-direction: column; text-decoration: none;
  border-top: 1px solid var(--hair); padding-top: 1.4rem;
}
.prod__shot {
  background: var(--paper-2); border-radius: var(--rad);
  aspect-ratio: 1 / 1; overflow: hidden; margin-bottom: 1.2rem;
  display: flex; align-items: center; justify-content: center;
}
.prod__shot img { width: 100%; height: 100%; object-fit: cover; transition: transform .3s ease; }
.prod:hover .prod__shot img { transform: scale(1.03); }
.prod__name { font-family: var(--display); font-size: 1.3rem; font-weight: 500; margin: 0 0 .35rem; }
.prod__line { font-size: .98rem; color: var(--ink-2); margin: 0 0 1rem; }
.prod__foot { margin-top: auto; display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.prod__price { font-family: var(--display); font-size: 1.25rem; font-weight: 500; }
.prod__per { font-size: .88rem; color: var(--silver); }
.prod__go { font-size: .95rem; font-weight: 600; color: var(--sig-ink); }

/* "Best for" is a scoped claim, which is the only kind allowed here. There is
   deliberately no overall rating anywhere in this stylesheet. */
.bestfor {
  display: inline-block; font-family: var(--display); font-size: .78rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--sig-ink); background: var(--sig-tint); border: 1px solid var(--sig-hair);
  padding: .3rem .7rem; border-radius: 2px; margin-bottom: .9rem;
}

/* --------------------------------------------------------- 9 product page */
.pdp { display: grid; grid-template-columns: 1.05fr 1fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
.pdp-gallery { position: sticky; top: 108px; }
.pdp-main {
  background: var(--paper-2); border-radius: var(--rad); overflow: hidden;
  aspect-ratio: 1 / 1; margin-bottom: .9rem;
}
.pdp-main img { width: 100%; height: 100%; object-fit: cover; }
.pdp-thumbs { display: grid; grid-template-columns: repeat(5, 1fr); gap: .6rem; }
.pdp-thumb {
  background: var(--paper-2); border: 2px solid transparent; border-radius: var(--rad);
  padding: 0; cursor: pointer; overflow: hidden; aspect-ratio: 1 / 1;
}
.pdp-thumb[aria-current="true"] { border-color: var(--ink); }
.pdp-thumb img { width: 100%; height: 100%; object-fit: cover; }

.pdp h1 { font-size: clamp(2.1rem, 3.6vw, 3rem); margin-bottom: .5rem; }
.pdp-sub { font-size: 1.18rem; color: var(--ink-2); margin-bottom: 1.6rem; }
.pdp-price { display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap; margin-bottom: .4rem; }
.pdp-price b { font-family: var(--display); font-size: 2.2rem; font-weight: 500; }
.pdp-price span { color: var(--silver); font-size: 1rem; }
.pdp-buy { margin: 1.6rem 0 1rem; display: grid; gap: .8rem; }
.pdp-reassure { display: grid; gap: .55rem; margin: 1.2rem 0 0; padding: 0; list-style: none; }
.pdp-reassure li { display: flex; gap: .6rem; align-items: flex-start; font-size: .98rem; color: var(--ink-2); }
.pdp-reassure svg { width: 20px; height: 20px; flex: 0 0 20px; margin-top: 3px; }

.gap-box {
  border-left: 3px solid var(--sig); background: var(--sig-tint);
  padding: 1.5rem 1.7rem; margin: 2rem 0; border-radius: 0 var(--rad) var(--rad) 0;
}
.gap-box p { margin: 0; font-size: 1.06rem; }

/* The pair that makes the page trustworthy. They are the same size on purpose:
   the moment "not ideal for" gets smaller than "best for", it is decoration. */
.fitgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 0; border: 1px solid var(--hair); border-radius: var(--rad); overflow: hidden; }
.fit { padding: 1.6rem 1.7rem; }
.fit + .fit { border-left: 1px solid var(--hair); }
.fit h4 { margin-bottom: .9rem; font-size: 1.05rem; }
.fit ul { margin: 0; padding: 0; list-style: none; display: grid; gap: .7rem; }
.fit li { font-size: .99rem; line-height: 1.5; padding-left: 1.5rem; position: relative; color: var(--ink-2); }
.fit--yes li::before { content: ''; position: absolute; left: 0; top: .55em; width: 9px; height: 9px; border-radius: 50%; background: var(--ok); }
.fit--no li::before { content: ''; position: absolute; left: 0; top: .78em; width: 11px; height: 2px; background: var(--silver); }

.spec { width: 100%; border-collapse: collapse; }
.spec th, .spec td { text-align: left; padding: .95rem 0; border-bottom: 1px solid var(--hair); font-size: 1rem; vertical-align: top; }
.spec th { font-weight: 500; color: var(--silver); width: 44%; font-family: var(--display); }

.tickset { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem; }
.tickset li { display: flex; gap: .75rem; align-items: flex-start; }
.tickset svg { width: 21px; height: 21px; flex: 0 0 21px; margin-top: 4px; }

/* ---------------------------------------------------------- 10 comparison */
.cmp-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.cmp { border-collapse: collapse; min-width: 780px; width: 100%; }
.cmp th, .cmp td { padding: 1rem .9rem; border-bottom: 1px solid var(--hair); text-align: left; font-size: .98rem; vertical-align: top; }
.cmp thead th { font-family: var(--display); font-size: 1.05rem; font-weight: 500; border-bottom: 2px solid var(--ink); }
.cmp tbody th { font-weight: 500; color: var(--silver); font-family: var(--display); position: sticky; left: 0; background: var(--paper); }
.cmp td b { font-family: var(--display); font-weight: 500; }

/* ------------------------------------------------------------- 11 finder */
.finder { border: 1px solid var(--hair); border-radius: var(--rad); background: var(--paper); }
.finder__step { padding: clamp(1.8rem, 4vw, 2.8rem); }
.finder__step[hidden] { display: none; }
.finder__q { font-family: var(--display); font-size: clamp(1.5rem, 3vw, 2rem); margin-bottom: 1.6rem; }
.finder__opts { display: grid; gap: .8rem; margin-bottom: 1.8rem; }
.finder__opt {
  display: flex; align-items: center; gap: 1rem; width: 100%;
  min-height: 66px; padding: 1rem 1.3rem; text-align: left;
  background: var(--paper); border: 2px solid var(--hair); border-radius: var(--rad);
  font-family: var(--body); font-size: 1.05rem; color: var(--ink); cursor: pointer;
}
.finder__opt:hover { border-color: var(--ink); background: var(--paper-2); }
.finder__opt[aria-pressed="true"] { border-color: var(--sig-ink); background: var(--sig-tint); }
.finder__prog { display: flex; gap: .4rem; padding: 0 clamp(1.8rem, 4vw, 2.8rem); padding-top: 1.6rem; }
.finder__prog i { flex: 1; height: 4px; background: var(--paper-3); border-radius: 2px; }
.finder__prog i.on { background: var(--sig); }
.finder__out { padding: clamp(1.8rem, 4vw, 2.8rem); border-top: 1px solid var(--hair); }

/* --------------------------------- 12 editorial, guides, policy, notices */
.article { max-width: 68ch; }
.article h2 { margin-top: 2.6rem; }
.article h3 { margin-top: 2rem; }
.article ul, .article ol { padding-left: 1.3rem; margin: 0 0 1.4em; }
.article li { margin-bottom: .6em; max-width: 64ch; }

.guide-list { display: grid; gap: 0; border-top: 1px solid var(--hair); }
.guide {
  display: grid; grid-template-columns: 150px 1fr auto; gap: 1.8rem; align-items: center;
  padding: 1.7rem 0; border-bottom: 1px solid var(--hair); text-decoration: none;
}
.guide:hover .guide__t { color: var(--sig-ink); }
.guide img { border-radius: var(--rad); aspect-ratio: 3/2; object-fit: cover; width: 100%; }
.guide__t { font-family: var(--display); font-size: 1.3rem; font-weight: 500; margin: 0 0 .3rem; }
.guide__s { font-size: .99rem; color: var(--silver); margin: 0; max-width: 62ch; }
.guide__go { font-size: 1.4rem; color: var(--silver); }

.notice {
  border: 1px solid var(--hair); border-left: 3px solid var(--silver);
  background: var(--paper-2); padding: 1.3rem 1.5rem; border-radius: 0 var(--rad) var(--rad) 0;
}
.notice p:last-child { margin-bottom: 0; }
.notice--sig { border-left-color: var(--sig); background: var(--sig-tint); }

.faq { border-top: 1px solid var(--hair); }
.faq details { border-bottom: 1px solid var(--hair); }
.faq summary {
  list-style: none; cursor: pointer; padding: 1.3rem 2.5rem 1.3rem 0;
  font-family: var(--display); font-size: 1.15rem; position: relative; min-height: 54px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+'; position: absolute; right: .4rem; top: 1.05rem;
  font-size: 1.6rem; color: var(--silver); line-height: 1;
}
.faq details[open] summary::after { content: '\2212'; }
.faq .faq__a { padding: 0 2.5rem 1.4rem 0; }
.faq .faq__a p:last-child { margin-bottom: 0; }

.crumbs { font-size: .92rem; color: var(--silver); padding: .9rem 0 0; }
.crumbs a { text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }
.crumbs span { margin: 0 .5rem; opacity: .5; }

/* ------------------------------------------------------------- 13 footer */
.site-footer { background: var(--ink); color: #C7CCCF; padding: clamp(3.5rem, 6vw, 5rem) 0 2.5rem; }
.site-footer a { color: #C7CCCF; text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.foot-top { display: grid; grid-template-columns: 1.5fr repeat(4, 1fr); gap: 2.5rem; padding-bottom: 3rem; }
.foot-brand img { height: 52px; width: auto; margin-bottom: 1.2rem; }
.foot-brand p { color: #98A0A5; font-size: .98rem; max-width: 32ch; }
.foot-col h5 {
  font-family: var(--display); font-size: .76rem; font-weight: 600; letter-spacing: .17em;
  text-transform: uppercase; color: #fff; margin: 0 0 1.1rem;
}
.foot-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }
.foot-col li { font-size: .98rem; }
.foot-bottom {
  border-top: 1px solid #2A3237; padding-top: 2rem;
  display: flex; flex-wrap: wrap; gap: 1.2rem 2rem; justify-content: space-between;
  font-size: .9rem; color: #8B9398;
}
.foot-legal { max-width: 78ch; font-size: .87rem; color: #7E868B; line-height: 1.6; margin-top: 1.6rem; }

/* ----------------------------------------------------------- 14 line art */
/* Ported from the Digilu .la system: hairline ink, a real recognisable
   subject, and the accent spent exactly once per drawing on the stroke that
   carries the meaning. Every stroke carries pathLength="1" so the draw-on is
   one transition with nothing measured in script. */
.la { display: block; width: 100%; height: auto; overflow: visible; }
.la-ink, .la-det, .la-acc, .la-ghost {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.la-ink   { stroke: var(--ink);    stroke-width: 1.9; }
.la-det   { stroke: var(--ink-2);  stroke-width: 1.3; opacity: .8; }
.la-ghost { stroke: var(--silver); stroke-width: 1;   opacity: .45; }
.la-acc   { stroke: var(--sig);    stroke-width: 2.4; }
.la-dot   { fill: var(--sig); stroke: none; }
.la-fill  { fill: var(--paper); stroke: none; }
.la--dark .la-ink   { stroke: #E8EBEC; }
.la--dark .la-det   { stroke: #97A0A5; }
.la--dark .la-ghost { stroke: #5B6469; }
.la--dark .la-fill  { fill: var(--ink); }

/* The drawing is VISIBLE by default; the entrance is opt-in, added by script.
   The other way round is how a page ends up with an empty column: if the
   observer never fires, or JavaScript is blocked, the drawing is simply gone.
   An animation that fails should cost the animation, never the artwork.

   This used to be a stroke-dashoffset draw-on, which looked better and did not
   survive contact with reality: `pathLength="1"` does not normalise the dash
   values once `vector-effect: non-scaling-stroke` is in play, so the computed
   offset stayed at 1px and every stroke rendered invisible while the filled
   accent dot rendered fine. A quiet rise is worth less than a drawing that is
   definitely on the page. */
.la--anim {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .7s ease, transform .7s cubic-bezier(.4, 0, .2, 1);
}
.la--anim.drawn { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .la--anim { opacity: 1; transform: none; transition: none; }
}

.lineart-band { padding: 1rem 0 0; }
.lineart-band .la { max-height: 220px; }
.lineart-figure { width: 100%; max-width: 560px; margin: 0 auto; }
.lineart-figure .la { width: 100%; height: auto; }
.page-hero__mark { max-width: 300px; }

/* ------------------------------------------------------- 15 responsive */
@media (max-width: 1100px) {
  .nav-link { padding: 1.1rem .7rem; font-size: .97rem; }
  .mega-menu { min-width: 560px; }
  .mega-menu--wide { min-width: 700px; }
}

@media (max-width: 980px) {
  :root { --gut: 1.5rem; --fs-body: 1.0625rem; }
  .primary-nav, .header-cta .btn { display: none; }
  .menu-toggle { display: block; }
  .header-cta { margin-left: auto; }
  .hero-inner { grid-template-columns: 1fr; }
  .hero-media { order: -1; }        /* the photograph leads on a phone */
  .split { grid-template-columns: 1fr; }
  .g-3, .g-4, .prod-grid { grid-template-columns: repeat(2, 1fr); }
  .need-grid { grid-template-columns: repeat(2, 1fr); }
  .need:first-child { border-left: 0; }
  .need:nth-child(odd) { border-left: 1px solid var(--hair); }
  .pdp { grid-template-columns: 1fr; }
  .pdp-gallery { position: static; }
  .foot-top { grid-template-columns: repeat(2, 1fr); }
  .guide { grid-template-columns: 110px 1fr; }
  .guide__go { display: none; }
}

@media (max-width: 620px) {
  :root { --gut: 1.25rem; }
  h1 { font-size: clamp(2.1rem, 9vw, 2.8rem); }
  .g-2, .g-3, .g-4, .prod-grid { grid-template-columns: 1fr; }
  .need-grid { grid-template-columns: 1fr; }
  .need, .need:nth-child(odd) { border-left: 1px solid var(--hair); }
  .fitgrid { grid-template-columns: 1fr; }
  .fit + .fit { border-left: 0; border-top: 1px solid var(--hair); }
  .foot-top { grid-template-columns: 1fr; gap: 2rem; }
  .pdp-thumbs { grid-template-columns: repeat(4, 1fr); }
  .btn { width: 100%; }
  .btn-row { gap: .75rem; }
  .guide { grid-template-columns: 1fr; gap: 1rem; }
  .guide img { max-width: 200px; }
  .trustline { gap: .8rem 1.4rem; font-size: .92rem; }
}

/* ------------------------------------------- 16 mobility: the actual business */
/* A "Reviewing" flag is visually quieter than a use-case flag on purpose: it is
   an honest status, not a claim, and it must not read as a badge of merit. */
.bestfor--hold {
  color: var(--silver); background: var(--paper-2); border-color: var(--hair);
}
.prod__ph {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1 / 1; background: var(--paper-2); border-radius: var(--rad);
  margin-bottom: 1.2rem;
}
.prod__ph svg { width: 64px; height: 64px; }

/* Provenance, shown inline. Every published specification says where it came
   from, and an unverified one says that instead of showing a plausible guess. */
.srcflag {
  display: inline-block; margin-left: .6rem; font-size: .72rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--silver); vertical-align: middle;
}
.spec td.pend { color: var(--silver); font-style: italic; }

.guide--slim { grid-template-columns: 1fr; padding: 1.1rem 0; }
.guide--slim .guide__t { font-size: 1.1rem; }

.pdp-main--art {
  display: flex; align-items: center; justify-content: center; padding: 2rem;
  background: var(--paper-2);
}
.pdp-main--art svg { width: 100%; height: auto; }

.hero--mob .hero-media img { border-radius: var(--rad); }

/* ------------------------------------------------------ 17 the video hero */
/* Full bleed, text laid over the footage, no control furniture on top of it.

   The pause button is gone and the obligation is not: WCAG 2.2.2 only applies
   to moving content that runs longer than five seconds, so the loop is 4.5s.
   prefers-reduced-motion still stops it dead. The video is aria-hidden and
   untabbable because it carries no information the copy does not already say,
   so a screen reader should walk straight past it. */
.vhero {
  position: relative;
  min-height: clamp(430px, 62vh, 620px);
  display: flex; align-items: center;
  overflow: hidden;
  background: var(--ink);
}
.vhero--cat { min-height: clamp(360px, 50vh, 500px); }

.vhero__media { position: absolute; inset: 0; }
.vhero__vid {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Crop takes from the LEFT so the subject stays large and right of centre,
     which is what leaves the copy a clean field to sit on. */
  object-position: 72% 42%;
  display: block;
}
/* The scrim is what makes text on video legible at every width. Two stops, so
   the left edge is dark enough for white type and the right stays photographic. */
.vhero__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(100deg, rgba(12,15,18,.94) 0%, rgba(12,15,18,.86) 26%,
                    rgba(12,15,18,.55) 50%, rgba(12,15,18,.12) 74%, rgba(12,15,18,0) 100%),
    linear-gradient(to top, rgba(12,15,18,.5), rgba(12,15,18,0) 45%);
}

.vhero__inner { position: relative; z-index: 2; width: 100%; padding-top: 2.2rem; padding-bottom: 2.2rem; }
.vhero__copy { max-width: 34rem; }
.vhero h1 {
  color: #fff; margin: 0 0 1rem;
  font-size: clamp(2.5rem, 5.2vw, 4rem); line-height: 1.02;
}
.vhero--cat h1 { font-size: clamp(2rem, 3.8vw, 3rem); }
.eyebrow--on { color: var(--sig); }
.lede--on { color: #DCE1E4; margin-bottom: 1.8rem; max-width: 46ch; }
.btn--onvid { border-color: rgba(255,255,255,.75); color: #fff; background: transparent; }
.btn--onvid:hover { background: #fff; color: var(--ink); border-color: #fff; }
/* Sits in the copy column, not out over the photograph: text laid on the busy
   half of a frame is a contrast failure waiting for the next breakpoint. */
.vhero__cap {
  margin: 1.6rem 0 0; font-size: .92rem; color: rgba(255,255,255,.68);
  max-width: 44ch; padding-top: 1.1rem;
  border-top: 1px solid rgba(255,255,255,.16);
}
.vhero__cap b { color: #fff; font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
  .vhero__vid { display: none; }
  .vhero__media { background-image: var(--vhero-poster); background-size: cover; background-position: 72% 42%; }
}

/* The graphical element: the mark drawn as a hairline across the seam between
   the hero and the page, so the video reads as part of the design rather than
   a rectangle dropped on top of it. */
.trustbar {
  background: var(--ink); color: #C7CCCF;
  border-top: 1px solid rgba(255,255,255,.10);
}
.trustbar__in {
  display: flex; flex-wrap: wrap; gap: .9rem 2.4rem;
  padding-top: 1.1rem; padding-bottom: 1.1rem;
  font-size: .96rem;
}
.trustbar__in span { display: flex; align-items: center; gap: .55rem; }
.trustbar__in svg { width: 20px; height: 20px; flex: 0 0 20px; }

@media (max-width: 860px) {
  .vhero { min-height: 0; }
  .vhero__inner { padding-top: 2.6rem; padding-bottom: 2.6rem; }
  .vhero__scrim {
    background: linear-gradient(180deg, rgba(12,15,18,.55) 0%, rgba(12,15,18,.86) 55%, rgba(12,15,18,.94) 100%);
  }
  .vhero__vid { object-position: 60% 30%; }
  .vhero__copy { max-width: none; }
  .vhero__cap { max-width: none; }
  .trustbar__in { flex-direction: column; gap: .6rem; }
}

/* ------------------------------------------------- 18 the category we define */
/* The definition is quoted verbatim wherever it appears, so it gets one
   treatment everywhere and reads as a definition rather than as copy. */
.defbox {
  font-family: var(--display);
  font-size: clamp(1.2rem, 2vw, 1.5rem);
  line-height: 1.4;
  color: var(--ink);
  border-left: 3px solid var(--sig);
  padding: .3rem 0 .3rem 1.4rem;
  margin: 0 0 1.4rem;
  max-width: 40ch;
}
.stages { display: grid; gap: 0; border-top: 1px solid var(--hair); }
.stage {
  display: grid; grid-template-columns: 3rem 1fr; gap: 1.4rem;
  padding: 1.6rem 0; border-bottom: 1px solid var(--hair);
}
.stage__n {
  font-family: var(--display); font-size: 1.5rem; font-weight: 500;
  color: var(--sig-ink); line-height: 1;
}
.stage h3 { font-size: 1.25rem; margin: 0 0 .4rem; }
.stage p { margin: 0; color: var(--ink-2); }
@media (max-width: 620px) {
  .stage { grid-template-columns: 2.2rem 1fr; gap: 1rem; }
}

/* The promise sits between the headline and the buttons: it is the one line the
   brand is claiming, so it gets its own weight rather than hiding in the lede. */
.vhero__promise {
  font-family: var(--display); font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase;
  font-size: .95rem; color: var(--sig);
  margin: 0 0 1.6rem;
}
.vhero__promise--dark { color: var(--sig-ink); margin-bottom: 1.2rem; }

/* ------------------------------------------------------- 19 contact capture */
/* Appears AFTER the recommendation is already on screen. Nothing is gated: a
   locked result behind an email is a deceptive pattern and the brief bans it. */
.capture {
  margin-top: 2.4rem; padding-top: 2rem; border-top: 1px solid var(--hair);
  display: grid; gap: .5rem; max-width: 34rem;
}
.capture h3 { margin: 0 0 .3rem; }
.capture label { font-weight: 500; font-size: .98rem; margin-top: .7rem; }
.capture input[type=text], .capture input[type=email], .capture textarea {
  font: inherit; font-size: 1.05rem; padding: .8rem .9rem; min-height: 54px;
  border: 1px solid var(--hair); border-radius: var(--rad);
  background: var(--paper); color: var(--ink); width: 100%;
}
.capture textarea { min-height: 96px; resize: vertical; }
.capture input:focus-visible, .capture textarea:focus-visible { outline: var(--focus); outline-offset: 1px; }
.capture .chk {
  display: flex; gap: .7rem; align-items: flex-start;
  font-weight: 400; font-size: .98rem; margin: 1rem 0 .4rem;
}
.capture .chk input { width: 22px; height: 22px; margin: 2px 0 0; flex: 0 0 22px; }
.capture button { margin-top: .6rem; justify-self: start; }
/* The honeypot. Off-screen rather than display:none, because some autofillers
   skip hidden fields and we want a bot to find it. */
.capture .hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

/* MEGAMENU-PLACEMENT:START — generated by ecosystem-site-engine/modules/megamenu; do not hand-edit */
/* Mega-menu placement — centered, viewport-clamped, never below the fold.
 * Generated by ecosystem-site-engine/modules/megamenu (kit v1.0.0).
 * Positioning only: this block sets no colour, size, padding or type.
 * --mm-shift and --mm-maxh are written by js/megamenu-placement.js. */
.mega-menu{
  left:50%;
  right:auto;
  margin-left:var(--mm-shift, 0px);
  transform:translateX(-50%) translateY(6px);
}
/* A right-aligned variant is no longer a different anchor: everything centres
 * and the clamp decides how far it may slide. The class stays a no-op so old
 * markup keeps working. */
.mega-menu--r{left:50%;right:auto}
.nav-item:hover .mega-menu, .nav-item:focus-within .mega-menu{transform:translateX(-50%) translateY(0)}
/* The fold guard. max-height is unset until the script measures a real window,
 * so a panel that fits is untouched and keeps its shadow. */
.mega-menu-inner{
  max-height:var(--mm-maxh, none);
  overflow-y:auto;
  overscroll-behavior:contain;
}
/* MEGAMENU-PLACEMENT:END */

/* ============================================================
   DIGILU SIGNAL GRID: the house field, inside the badge already here
   ============================================================
   Four cells and a hairline, from the back of the Digilu business card, so
   every mark in the ecosystem shares one field. Felt rather than read.

   Only .prod__ph. It is already a painted square box holding a 64px mark, so
   the grid goes inside the box that exists. .need__mark is a bare 46px svg with
   no box at all: it would need a plate rather than a grid, which is a design
   decision on a live product page and not a CSS retrofit.

   CSS only. Delete this block and the site is exactly as it was.
   ============================================================ */
:root{ --dg-signal-grid:rgba(26,42,52,.075); }

.prod__ph{
  background-image:
    linear-gradient(to right,  var(--dg-signal-grid) 0 1px, transparent 1px),
    linear-gradient(to bottom, var(--dg-signal-grid) 0 1px, transparent 1px);
  background-size: 14px 14px;
  background-position: center center;
}

/* .need__mark is a bare 46px mark with no box, the one place in the ecosystem
   where the field needs a plate built for it rather than a badge that already
   exists. Mike approved it 2026-08-22.

   The plate is the house one: a rounded square on paper, the 14px cell, and a
   hairline so the box has an edge on a light page. The mark keeps its size and
   is centred, so nothing about the drawing changes. */
.need__mark{
  display:inline-flex; align-items:center; justify-content:center;
  width:76px; height:76px; border-radius:17px;
  background:var(--paper-2, #f4f2ee);
  box-shadow: inset 0 0 0 1px rgba(26,42,52,.10);
  background-image:
    linear-gradient(to right,  var(--dg-signal-grid) 0 1px, transparent 1px),
    linear-gradient(to bottom, var(--dg-signal-grid) 0 1px, transparent 1px);
  background-size: 14px 14px;
  background-position: center center;
}
