/* ==========================================================================
   Gravl marketing site
   --------------------------------------------------------------------------
   Design language: technical drawing. White sheet, ink linework, one blueprint
   blue, and a faint drafting grid. The motifs are borrowed from plan sheets
   because that is literally what the product reads: dimension lines with tick
   ends, corner registration marks, mono annotation labels in caps, and a title
   block. Nothing is decorative for its own sake.

   Rules carried over from the Gravl Deck Standard: one accent, hairline rules
   only, no zebra banding, sentence case titles, all caps reserved for
   annotations and table headers, numbers always in mono, and no dashes in any
   copy on the page.
   ========================================================================== */

/* --- 1. Tokens ----------------------------------------------------------- */

:root {
  --sheet: #ffffff;
  --ink: #0f1115;
  --blue: #1b4dff;
  --blue-ink: #1330a8; /* blue dark enough for small text on white */
  --blue-wash: #eef2ff;
  --grid: #d9e2ff;

  --secondary: #454b57;
  --muted: #878d99;
  --hairline: #e3e6ec;
  --rule-hard: #b9bfcb;

  /* The reference series in the impact model. Deliberately achromatic: it is a
     baseline, not a peer category, so it recedes and the blue reads as the
     subject. It carries a dashed stroke and a direct label so identity never
     depends on color alone. */
  --series-ref: #8a8f98;

  --font: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --content: 1180px;
  --gutter: 30px;
}

/* --- 2. Base ------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--sheet);
  color: var(--secondary);
  font-family: var(--font);
  font-size: 16.5px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: var(--font);
  color: var(--ink);
  font-weight: 700;
  letter-spacing: -0.025em;
  margin: 0 0 0.45em;
}
h1 {
  font-size: clamp(2.5rem, 5.4vw, 4.05rem);
  line-height: 1.02;
}
h2 {
  font-size: clamp(1.7rem, 3.1vw, 2.35rem);
  line-height: 1.1;
}
h3 {
  font-size: 1rem;
  line-height: 1.28;
  letter-spacing: -0.01em;
}

p {
  margin: 0 0 1em;
  max-width: 64ch;
}
strong {
  color: var(--ink);
  font-weight: 600;
}
a {
  color: var(--ink);
}

/* --- 3. Layout ----------------------------------------------------------- */

.wrap {
  max-width: var(--content);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

section {
  padding: 84px 0;
  border-top: 1px solid var(--hairline);
  position: relative;
}

/* The annotation label. Mono, caps, wide tracked, blue. This is the drafting
   voice of the page and it is the only place caps are allowed alongside table
   headers. */
.anno {
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--blue-ink);
  margin: 0 0 16px;
  display: flex;
  align-items: center;
  gap: 10px;
}
/* A short leader rule before the label, like a callout on a drawing. */
.anno::before {
  content: "";
  width: 22px;
  height: 1px;
  background: var(--blue);
  flex: 0 0 22px;
}

.lede {
  font-size: 1.1rem;
  color: var(--secondary);
  max-width: 58ch;
}

.num {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

/* --- 4. Header ----------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: saturate(1.6) blur(8px);
  border-bottom: 1px solid var(--hairline);
}
.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  height: 64px;
}
.brand {
  display: flex;
  align-items: baseline;
  gap: 9px;
  text-decoration: none;
}
/* The wordmark, set live rather than placed as an image. The chevron sits in
   for the a, sized off the lowercase x height so it optically matches the
   letters either side of it rather than the cap height, which would sit high. */
.wm {
  font-family: var(--font);
  font-weight: 700;
  font-size: 1.32rem;
  letter-spacing: -0.045em;
  color: var(--ink);
  line-height: 1;
  display: inline-flex;
  align-items: baseline;
}
.wm-a {
  height: 0.84em;
  width: auto;
  display: inline-block;
  margin: 0 0.02em;
  transform: translateY(0.05em);
}
.brand .tag {
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  padding-left: 9px;
  border-left: 1px solid var(--hairline);
}
.site-nav {
  display: flex;
  gap: 24px;
  align-items: center;
}
.site-nav a {
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--secondary);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
}
.site-nav a:hover {
  color: var(--ink);
  border-bottom-color: var(--blue);
}

/* --- 5. Buttons and controls -------------------------------------------- */

.btn {
  display: inline-block;
  font-family: var(--font);
  font-size: 0.88rem;
  font-weight: 600;
  padding: 11px 21px;
  border: 1px solid var(--ink);
  text-decoration: none;
  cursor: pointer;
  transition: background 130ms ease, color 130ms ease, border-color 130ms ease;
}
.btn-primary {
  background: var(--ink);
  color: #fff;
}
.btn-primary:hover {
  background: var(--blue);
  border-color: var(--blue);
}
.btn-ghost {
  background: transparent;
  color: var(--ink);
}
.btn-ghost:hover {
  border-color: var(--blue);
  color: var(--blue-ink);
}

/* --- 6. Hero ------------------------------------------------------------- */

.hero {
  border-top: 0;
  padding: 74px 0 70px;
  position: relative;
  overflow: hidden;
}

/* The drafting grid. Two repeating gradients at 28px, plus a heavier line every
   fifth square, faded out toward the bottom so it never competes with copy. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 28px 28px;
  -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.5), transparent 78%);
  mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.5), transparent 78%);
  pointer-events: none;
}
.hero .wrap {
  position: relative;
  z-index: 1;
}

.hero-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 54px;
  align-items: center;
}
.hero h1 {
  max-width: 13ch;
}
.hero .lede {
  font-size: 1.16rem;
  max-width: 46ch;
}
.hero-actions {
  display: flex;
  gap: 11px;
  flex-wrap: wrap;
  margin-top: 26px;
}

/* --- 7. Plan sheet demo -------------------------------------------------- */

/* A mock plan sheet with a title block, drawn in SVG, that cycles through the
   four things the extractor actually returns. It is the product demonstration
   without a video and without exposing a real customer document. */
.sheet {
  border: 1px solid var(--ink);
  background: #fff;
  position: relative;
}
@media (prefers-reduced-motion: reduce) {
  .sheet-body {
    transform: none !important;
  }
  .pageshade {
    opacity: 0 !important;
  }
}
.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--ink);
  font-family: var(--mono);
  font-size: 0.63rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
}
.sheet-head .live {
  display: flex;
  align-items: center;
  gap: 7px;
  color: var(--blue-ink);
}
.sheet-head .dot {
  width: 6px;
  height: 6px;
  background: var(--blue);
  border-radius: 50%;
  animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.25;
  }
}
/* --- the paper -----------------------------------------------------------
   The sheet is a viewer holding a stack of paper on a desk. Three things do
   the work: a desk tone behind, a real shadow under the top sheet, and two
   sheets offset behind it so the set has depth standing still. The turn is a
   rotation on the left edge, the way paper actually behaves.
   ------------------------------------------------------------------------ */

.sheet-stage {
  position: relative;
  padding: 15px 17px 17px 15px;
  background: #f1f2f5;
  /* Clipped, because the turning sheet is being watched through the viewer
     rather than floating out of it. A long perspective keeps the near edge
     from ballooning as it swings. */
  overflow: hidden;
  perspective: 2600px;
  perspective-origin: 50% 50%;
}

.paper {
  background: #fff;
  border: 1px solid rgba(15, 17, 21, 0.1);
}
/* The two beneath, peeking out bottom right. */
.paper.under1,
.paper.under2 {
  position: absolute;
  top: 15px;
  left: 15px;
  right: 17px;
  bottom: 17px;
}
.paper.under1 {
  transform: translate(3px, 3px);
  box-shadow: 0 1px 2px rgba(15, 17, 21, 0.05);
}
.paper.under2 {
  transform: translate(6px, 6px);
  background: #fbfbfc;
}

.sheet-body {
  position: relative;
  z-index: 2;
  overflow: hidden;
  transform-origin: left center;
  will-change: transform;
  box-shadow: 0 1px 2px rgba(15, 17, 21, 0.07), 0 7px 18px rgba(15, 17, 21, 0.11);
}
.sheet svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Shading on the turning page. Paper swinging toward you catches light on the
   free edge and loses it at the hinge, so the gradient runs the other way from
   what you would guess. */
.pageshade {
  position: absolute;
  inset: 0;
  z-index: 3;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(
    90deg,
    rgba(15, 17, 21, 0.22) 0%,
    rgba(15, 17, 21, 0.06) 34%,
    rgba(255, 255, 255, 0.5) 88%,
    rgba(255, 255, 255, 0.75) 100%
  );
}

/* Position through the set. 212 sheets is an abstraction until a bar crosses
   it, and the bar is what makes the page run legible as progress rather than
   as flicker. */
.pageprog {
  height: 2px;
  background: var(--hairline);
  position: relative;
}
.pageprog i {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  background: var(--blue);
  transition: width 90ms linear;
}

/* Buckets. Fixed categories across the foot of the sheet; findings drop in
   underneath as the scan runs. A second bid item stacks under the same header
   rather than producing a second identical one. */
.buckets {
  border-top: 1px solid var(--ink);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--hairline);
}
.bucket {
  background: #fff;
  padding: 11px 13px 14px;
  transition: background 260ms ease;
}
.bucket.is-item {
  --fcol: var(--blue);
  --fwash: #eef2ff;
}
.bucket.is-risk {
  --fcol: #c2410c;
  --fwash: #fdf1ea;
}
/* Pricing shares the warning hue with go or no go: both are conditions. The
   marker is hollow rather than solid, which says same family, lesser
   consequence, without spending a third colour on it. */
.bucket.is-price {
  --fcol: #c2410c;
  --fwash: #fdf6f2;
}
.bucket.is-price .bl li i {
  background: transparent;
  border: 1px solid var(--fcol);
}
.bucket.is-place {
  --fcol: var(--ink);
  --fwash: #f1f2f5;
}
.bucket[data-on="true"] {
  background: var(--fwash);
}
.bh {
  font-family: var(--mono);
  font-size: 0.55rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
  transition: color 260ms ease;
}
.bucket[data-on="true"] .bh {
  color: var(--fcol);
}
.bl {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  /* Two rows reserved. The tallest bucket holds two, and holding the height
     stops the sheet above jumping as entries arrive. */
  min-height: 42px;
}
.bl li {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--ink);
  padding: 2px 0;
  cursor: pointer;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 300ms ease, transform 300ms ease;
}
.bl li i {
  width: 5px;
  height: 5px;
  flex: 0 0 5px;
  background: var(--fcol);
  opacity: 0.4;
  transform: translateY(-1px);
  transition: opacity 260ms ease;
}
.bl li[data-found="true"] {
  opacity: 1;
  transform: none;
}
.bl li[data-active="true"] i {
  opacity: 1;
}
.bl li[data-active="true"] span {
  font-weight: 600;
}
.bl li:hover span {
  text-decoration: underline;
  text-decoration-color: var(--fcol);
  text-underline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .bl li {
    transition: none;
  }
}

/* --- 8. Stat strip ------------------------------------------------------- */

.stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--hairline);
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}
.stat {
  background: #fff;
  padding: 26px 22px 24px;
}
.stat .figure {
  font-family: var(--mono);
  font-size: 1.75rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.stat .label {
  font-family: var(--mono);
  font-size: 0.63rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-top: 10px;
  line-height: 1.5;
}
.stats-note {
  padding: 14px 0 0;
}

.footnote {
  font-family: var(--mono);
  font-size: 0.68rem;
  line-height: 1.65;
  color: var(--muted);
  max-width: 92ch;
  margin-top: 14px;
}

/* --- 9. Cards and panels ------------------------------------------------- */

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  margin-top: 36px;
}
.card {
  background: #fff;
  padding: 24px 22px 26px;
}
.card .n {
  font-family: var(--mono);
  font-size: 0.63rem;
  letter-spacing: 0.1em;
  color: var(--blue-ink);
  display: block;
  margin-bottom: 12px;
}
.card p {
  font-size: 0.92rem;
  margin-bottom: 0;
  color: var(--muted);
}

.panels {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  margin-top: 36px;
}
.panel {
  background: #fff;
  padding: 30px 28px 28px;
  position: relative;
}
/* Corner registration mark, top left of each panel. A drawing convention, and
   the cheapest way to make a plain box read as a technical object. */
.panel::before {
  content: "";
  position: absolute;
  top: 13px;
  left: 13px;
  width: 9px;
  height: 9px;
  border-top: 1px solid var(--blue);
  border-left: 1px solid var(--blue);
}
.panel .lbl {
  font-family: var(--mono);
  font-size: 0.63rem;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--muted);
  margin-bottom: 10px;
}
.panel h3 {
  font-size: 1.3rem;
  margin-bottom: 11px;
}
.panel ul {
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.93rem;
}
.panel li {
  padding: 8px 0 8px 20px;
  border-top: 1px solid var(--hairline);
  position: relative;
}
.panel li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 16px;
  width: 8px;
  height: 1px;
  background: var(--blue);
}


/* --- 16. Print ----------------------------------------------------------- */

/* A leave behind. The interactive chrome comes off, the argument stays, and the
   company record prints as a record. Nobody expects a marketing page to print
   properly, which is exactly why it should. */
@media print {
  :root {
    --hairline: #c9c9c9;
    --rule-hard: #8a8a8a;
    --muted: #5a5a5a;
    --secondary: #2a2a2a;
  }
  body {
    font-size: 10.5pt;
    line-height: 1.45;
  }
  body::after,
  .crop,
  .site-nav,
  .hero::before,
  .hero-actions,
  .scanline,
  .assump,
  .model-bar .segmented,
  .tableview summary {
    display: none !important;
  }
  .site-header {
    position: static;
    background: none;
    border-bottom: 1px solid var(--rule-hard);
  }
  section {
    padding: 18pt 0;
    break-inside: avoid;
  }
  .hero {
    padding: 12pt 0 18pt;
  }
  h1 {
    font-size: 26pt;
  }
  h2 {
    font-size: 15pt;
  }
  .hero-grid,
  .model-body {
    grid-template-columns: 1fr;
    gap: 18pt;
  }
  /* The dark band inverts, because printing a solid black panel wastes toner
     and reads worse than the same content on paper. */
  .band {
    background: none;
    color: var(--secondary);
    border-top: 1px solid var(--rule-hard);
  }
  .band h2,
  .band h3 {
    color: #000;
  }
  .band .lede,
  .band .card p {
    color: var(--secondary);
  }
  .band .cards,
  .band .card {
    background: none;
    border-color: var(--hairline);
  }
  /* The table view is the model on paper, since the chart's hover is useless
     there. Force it open. */
  .tableview[open] .inner,
  .tableview .inner {
    display: block;
  }
  .reveal {
    opacity: 1 !important;
    transform: none !important;
  }
  .identity {
    break-inside: avoid;
  }
  a[href^="mailto:"]::after {
    content: "";
  }
}

/* --- 9b. The pipeline ---------------------------------------------------- */

/* The platform drawn as a sequence. Everything inside is generated by app.js
   from the PIPE spec, so the picture and the animation cannot drift apart. */
.pipe {
  margin-top: 38px;
  border: 1px solid var(--hairline);
  padding: 22px 20px 18px;
  overflow-x: auto;
}
#pipeline {
  display: block;
  width: 100%;
  min-width: 760px;
  height: auto;
}

/* The one word that keeps the projection honest now that the paragraph under
   it is gone. Sits in the chart chrome, not in the copy. */
.legend .tagged {
  color: var(--muted);
  border: 1px solid var(--hairline);
  padding: 3px 8px;
  letter-spacing: 0.14em;
}

/* --- 10. Timeline -------------------------------------------------------- */

.rail {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  margin-top: 38px;
}
.stage {
  background: #fff;
  padding: 16px 14px 20px;
  transition: background 150ms ease;
}
.stage:hover {
  background: var(--blue-wash);
}
.stage .n {
  font-family: var(--mono);
  font-size: 0.66rem;
  color: #fff;
  background: var(--ink);
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  margin-bottom: 11px;
}
.stage.auto .n {
  background: var(--blue);
}
.stage h3 {
  font-size: 0.87rem;
  margin-bottom: 6px;
}
.stage p {
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--muted);
  margin: 0;
}

/* A dimension line, the way a drawing marks a span: a rule with tick ends and
   the measurement sitting on it. It marks which stages the software covers. */
.dim {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-top: 14px;
}
.dim-span {
  grid-column: 1 / 6;
  position: relative;
  height: 30px;
}
.dim-span::before {
  content: "";
  position: absolute;
  top: 8px;
  left: 0;
  right: 0;
  border-top: 1px solid var(--blue);
}
.dim-span::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 0;
  right: 0;
  height: 13px;
  border-left: 1px solid var(--blue);
  border-right: 1px solid var(--blue);
}
.dim-span span {
  position: absolute;
  top: 15px;
  left: 0;
  font-family: var(--mono);
  font-size: 0.63rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--blue-ink);
  background: #fff;
  padding-right: 8px;
}
.dim-rest {
  grid-column: 6 / 8;
  position: relative;
  height: 30px;
}
.dim-rest span {
  position: absolute;
  top: 15px;
  left: 0;
  font-family: var(--mono);
  font-size: 0.63rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
}
.dim-rest::before {
  content: "";
  position: absolute;
  top: 8px;
  left: 0;
  right: 0;
  border-top: 1px dashed var(--rule-hard);
}

/* --- 11. Impact model ---------------------------------------------------- */

.model {
  margin-top: 36px;
  border: 1px solid var(--hairline);
}
.model-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  padding: 14px 20px;
  border-bottom: 1px solid var(--hairline);
  background: #fcfcfd;
}

/* Segmented control for the metric. One row of filters above the chart, per the
   interaction spec. */
.segmented {
  display: inline-flex;
  border: 1px solid var(--rule-hard);
}
.segmented button {
  font-family: var(--font);
  font-size: 0.79rem;
  font-weight: 500;
  padding: 7px 14px;
  background: #fff;
  color: var(--secondary);
  border: 0;
  border-right: 1px solid var(--hairline);
  cursor: pointer;
}
.segmented button:last-child {
  border-right: 0;
}
.segmented button[aria-pressed="true"] {
  background: var(--ink);
  color: #fff;
}

.legend {
  display: flex;
  gap: 18px;
  align-items: center;
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--secondary);
}
.legend span {
  display: flex;
  align-items: center;
  gap: 7px;
}
.legend i {
  width: 18px;
  height: 0;
  border-top: 2px solid var(--blue);
}
.legend i.ref {
  border-top: 2px dashed var(--series-ref);
}

.model-body {
  display: grid;
  grid-template-columns: 1fr 268px;
}
.chart-pane {
  padding: 18px 12px 8px 4px;
  position: relative;
  min-width: 0;
}
.chart-pane svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--ink);
  color: #fff;
  padding: 9px 11px;
  font-family: var(--mono);
  font-size: 0.7rem;
  line-height: 1.55;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 110ms ease;
  z-index: 5;
}
.tooltip b {
  color: #fff;
  font-weight: 600;
}
.tooltip .sw {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 6px;
  vertical-align: baseline;
}

.assump {
  border-left: 1px solid var(--hairline);
  padding: 20px 20px 22px;
  background: #fcfcfd;
}
.assump h3 {
  font-family: var(--mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--muted);
  font-weight: 500;
  margin-bottom: 16px;
}
.field {
  margin-bottom: 18px;
}
.field label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.78rem;
  color: var(--secondary);
  margin-bottom: 7px;
}
.field label b {
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
/* The slider, made tactile. Three things do it: the track fills behind the
   thumb so it reads as a gauge, the thumb is a physical handle with a grip
   rather than a dot, and the hit area is 26px tall even though the track is 3.
   Ticks under the track give the travel a scale to move against. */
.field input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 26px;
  background: transparent;
  outline: none;
  cursor: grab;
  --p: 50%;
}
.field input[type="range"]:active {
  cursor: grabbing;
}

.field input[type="range"]::-webkit-slider-runnable-track {
  height: 3px;
  border-radius: 0;
  background: linear-gradient(
    to right,
    var(--blue) 0 var(--p),
    var(--rule-hard) var(--p) 100%
  );
}
.field input[type="range"]::-moz-range-track {
  height: 3px;
  background: var(--rule-hard);
}
.field input[type="range"]::-moz-range-progress {
  height: 3px;
  background: var(--blue);
}

/* A handle, not a dot. Two grip lines drawn with a repeating gradient, since a
   range thumb cannot carry pseudo elements. */
.field input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 15px;
  height: 22px;
  margin-top: -9.5px;
  border: 1px solid var(--ink);
  background-color: #fff;
  background-image: repeating-linear-gradient(
    to right,
    var(--rule-hard) 0 1px,
    transparent 1px 4px
  );
  background-repeat: no-repeat;
  background-position: center;
  background-size: 7px 8px;
  box-shadow: 0 1px 2px rgba(15, 17, 21, 0.14);
  cursor: grab;
  transition: transform 130ms ease, box-shadow 130ms ease,
    border-color 130ms ease;
}
.field input[type="range"]::-moz-range-thumb {
  width: 15px;
  height: 22px;
  border-radius: 0;
  border: 1px solid var(--ink);
  background-color: #fff;
  background-image: repeating-linear-gradient(
    to right,
    var(--rule-hard) 0 1px,
    transparent 1px 4px
  );
  background-repeat: no-repeat;
  background-position: center;
  background-size: 7px 8px;
  box-shadow: 0 1px 2px rgba(15, 17, 21, 0.14);
  cursor: grab;
}
.field input[type="range"]:hover::-webkit-slider-thumb {
  border-color: var(--blue);
}
.field input[type="range"]:active::-webkit-slider-thumb,
.field input[type="range"]:focus-visible::-webkit-slider-thumb {
  border-color: var(--blue);
  transform: scaleY(1.12);
  box-shadow: 0 2px 6px rgba(27, 77, 255, 0.24);
}
.field input[type="range"]:active::-moz-range-thumb {
  border-color: var(--blue);
}

/* Travel marks. Not clickable, just a scale for the thumb to move against. */
.ticks {
  height: 4px;
  margin-top: 2px;
  background-image: repeating-linear-gradient(
    to right,
    var(--hairline) 0 1px,
    transparent 1px 10%
  );
}

/* Held state. The readout above responds while the hand is on the slider. */
.field.is-live label b {
  color: var(--blue-ink);
}
.field.is-live .ticks {
  background-image: repeating-linear-gradient(
    to right,
    var(--rule-hard) 0 1px,
    transparent 1px 10%
  );
}

@media (prefers-reduced-motion: reduce) {
  .field input[type="range"]::-webkit-slider-thumb {
    transition: none;
  }
}

.assump-note {
  font-family: var(--mono);
  font-size: 0.63rem;
  line-height: 1.7;
  color: var(--muted);
  margin: 2px 0 16px;
}
.reset {
  font-family: var(--mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
}
.reset:hover {
  color: var(--blue-ink);
}

.model-out {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--hairline);
  border-top: 1px solid var(--hairline);
}
.out {
  background: #fff;
  padding: 16px 20px 18px;
}
.out .figure {
  font-family: var(--mono);
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--blue-ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.out .label {
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-top: 7px;
}

/* The table view. Required so the chart is never the only way to read the
   numbers, and it doubles as the honest disclosure of the model output. */
.tableview {
  border-top: 1px solid var(--hairline);
}
.tableview summary {
  font-family: var(--mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--muted);
  padding: 12px 20px;
  cursor: pointer;
}
.tableview summary:hover {
  color: var(--blue-ink);
}
.tableview .inner {
  padding: 0 20px 20px;
  overflow-x: auto;
}
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}
thead th {
  font-family: var(--mono);
  font-size: 0.63rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  text-align: right;
  padding: 0 10px 8px;
  border-bottom: 1px solid var(--rule-hard);
}
thead th:first-child {
  text-align: left;
}
tbody td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--hairline);
  text-align: right;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--secondary);
}
tbody td:first-child {
  text-align: left;
  color: var(--ink);
}


/* --- 11b. Field notes ---------------------------------------------------- */

/* Marginalia, set the way an engineer annotates a drawing: a rule down the
   left, an index above, and the source underneath. These are the only place on
   the site where the voice is first person observation rather than argument,
   and that contrast is the point. */
.notes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 30px 44px;
  margin-top: 40px;
}
.note {
  padding-left: 20px;
  border-left: 1px solid var(--hairline);
  position: relative;
}
/* The blue segment marks where the note begins, the way a callout starts at
   the thing it points to. */
.note::before {
  content: "";
  position: absolute;
  left: -1px;
  top: 0;
  width: 1px;
  height: 26px;
  background: var(--blue);
}
.note-n {
  font-family: var(--mono);
  font-size: 0.63rem;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--blue-ink);
  margin-bottom: 9px;
}
.note p {
  font-size: 0.96rem;
  line-height: 1.62;
  margin: 0 0 11px;
  max-width: 46ch;
  color: var(--secondary);
}
.note-src {
  font-family: var(--mono);
  font-size: 0.63rem;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--muted);
}
.note-src::before {
  content: "\2014\00a0\00a0";
}
/* A literal string or figure quoted from the field, set in mono so it reads as
   a thing that was actually typed rather than a turn of phrase. */
.lit {
  font-family: var(--mono);
  font-size: 0.88em;
  background: var(--blue-wash);
  padding: 1px 5px;
  color: var(--ink);
  white-space: nowrap;
}

@media (max-width: 860px) {
  .notes {
    grid-template-columns: 1fr;
    gap: 26px;
  }
}

/* --- 12. Dark band ------------------------------------------------------- */

.band {
  background: var(--ink);
  color: #a7adb9;
  border-top: 0;
}
.band h2 {
  color: #fff;
}
.band h3 {
  color: #fff;
}
.band .lede {
  color: #a7adb9;
}
.band .anno {
  color: #7d97ff;
}
.band .anno::before {
  background: #7d97ff;
}
.band .cards {
  background: #272b33;
  border-color: #272b33;
}
.band .card {
  background: var(--ink);
}
.band .card p {
  color: #8d93a0;
}
.band .card .n {
  color: #7d97ff;
}

/* --- 13. Contact and footer --------------------------------------------- */

/* The identity block is the know your business panel a bank reads: legal name,
   plain description, industry, location, and an address on the domain. It is
   load bearing. Do not remove it to tidy the design. */
.contact-grid {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: 44px;
  margin-top: 30px;
  align-items: start;
}
.identity {
  border: 1px solid var(--ink);
  padding: 0;
}
.identity .title-block {
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--muted);
  padding: 9px 18px;
  border-bottom: 1px solid var(--ink);
}
.identity dl {
  margin: 0;
  padding: 18px;
  display: grid;
  grid-template-columns: 92px 1fr;
  gap: 11px 16px;
  font-size: 0.87rem;
}
.identity dt {
  font-family: var(--mono);
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  padding-top: 3px;
}
.identity dd {
  margin: 0;
  color: var(--ink);
}

.site-footer {
  border-top: 1px solid var(--hairline);
  padding: 22px 0 36px;
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.site-footer .wrap {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

/* --- 14. Scroll reveal --------------------------------------------------- */

/* Deliberately small: an 8px rise and a fade, once, never repeating. Motion is
   there to sequence attention, not to perform. */
/* Hidden only when scripting is available. Without JS the page renders fully
   rather than blank, which matters because a bank's KYB reviewer may well be
   looking at this in a locked down browser. */
.js .reveal {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 520ms ease, transform 520ms ease;
}
.js .reveal.in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .js .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .sheet-head .dot {
    animation: none;
  }
}


/* --- 14b. Paper grain and crop marks ------------------------------------ */

/* A single tile of fractal noise, desaturated, at three percent. It is the
   difference between a page that looks printed and a page that looks rendered.
   Fixed rather than scrolled so it behaves like the surface rather than the
   content, and pointer-events none so it never intercepts a click. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0.032;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Crop marks, the way a printed sheet is trimmed. Four corners, fixed, hairline
   thin. They do nothing except tell you someone was thinking about the edges. */
.crop {
  position: fixed;
  z-index: 91;
  width: 14px;
  height: 14px;
  pointer-events: none;
  opacity: 0.45;
}
.crop.tl {
  top: 74px;
  left: 12px;
  border-top: 1px solid var(--rule-hard);
  border-left: 1px solid var(--rule-hard);
}
.crop.tr {
  top: 74px;
  right: 12px;
  border-top: 1px solid var(--rule-hard);
  border-right: 1px solid var(--rule-hard);
}
.crop.bl {
  bottom: 12px;
  left: 12px;
  border-bottom: 1px solid var(--rule-hard);
  border-left: 1px solid var(--rule-hard);
}
.crop.br {
  bottom: 12px;
  right: 12px;
  border-bottom: 1px solid var(--rule-hard);
  border-right: 1px solid var(--rule-hard);
}
@media (max-width: 1320px) {
  .crop {
    display: none;
  }
}

/* The section index. Drawings number their sheets; so does this. */
.anno .idx {
  color: var(--muted);
  letter-spacing: 0.1em;
}
.anno .idx::after {
  content: " /";
  color: var(--hairline);
}

/* Registration marks on the model panel, matching the ones on the two panels
   in "How we work" so the page reads as one drawing set. */
.model {
  position: relative;
}
.model::before,
.model::after {
  content: "";
  position: absolute;
  width: 9px;
  height: 9px;
  pointer-events: none;
}
.model::before {
  top: -1px;
  left: -1px;
  border-top: 1px solid var(--blue);
  border-left: 1px solid var(--blue);
}
.model::after {
  bottom: -1px;
  right: -1px;
  border-bottom: 1px solid var(--blue);
  border-right: 1px solid var(--blue);
}

/* --- 15. Responsive ------------------------------------------------------ */

@media (max-width: 1020px) {
  .hero-grid {
    grid-template-columns: 1fr;
    gap: 40px;
  }
  .hero h1 {
    max-width: 16ch;
  }
  .model-body {
    grid-template-columns: 1fr;
  }
  .assump {
    border-left: 0;
    border-top: 1px solid var(--hairline);
  }
}

@media (max-width: 860px) {
  .site-nav {
    display: none;
  }
  .stats,
  .cards,
  .panels {
    grid-template-columns: 1fr;
  }
  .contact-grid {
    grid-template-columns: 1fr;
    gap: 26px;
  }
  /* Redraw the rail vertically rather than letting seven columns collapse into
     unreadable slivers, and drop the dimension line, which only reads
     horizontally. */
  .rail {
    grid-template-columns: 1fr;
  }
  .dim {
    display: none;
  }
  .buckets {
    grid-template-columns: repeat(2, 1fr);
  }
  .wm {
    font-size: 1.2rem;
  }
  .model-out {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 560px) {
  section {
    padding: 56px 0;
  }
  .hero {
    padding: 48px 0 54px;
  }
}

/* --- 16b. Sub heading and seam ------------------------------------------ */

/* When two arguments share a section, the second one gets a rule and a
   smaller heading rather than its own eyebrow. It is one argument in two
   movements: you cannot hire your way through the stages, and here is what
   that costs you. */
.seam {
  border-top: 1px solid var(--hairline);
  margin: 64px 0 0;
}
.sub-h {
  font-size: clamp(1.3rem, 2.1vw, 1.6rem);
  line-height: 1.15;
  margin: 34px 0 0.5em;
}

/* --- 17. Section rail, palette, colophon --------------------------------- */

/* A sheet index for the page. Numbers down the left, the current one marked.
   Wide screens only: below that it would sit on top of the content. */
.srail {
  position: fixed;
  left: 30px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.srail a {
  display: flex;
  align-items: center;
  gap: 9px;
  text-decoration: none;
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  color: var(--muted);
  opacity: 0.55;
  transition: opacity 200ms ease, color 200ms ease;
}
.srail a i {
  display: block;
  width: 14px;
  height: 1px;
  background: var(--rule-hard);
  transition: width 220ms ease, background 220ms ease;
}
.srail a .rl {
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 200ms ease, transform 200ms ease;
  white-space: nowrap;
  text-transform: uppercase;
}
.srail a:hover,
.srail a[aria-current="true"] {
  opacity: 1;
  color: var(--blue-ink);
}
.srail a:hover i,
.srail a[aria-current="true"] i {
  width: 26px;
  background: var(--blue);
}
.srail:hover a .rl,
.srail a[aria-current="true"] .rl {
  opacity: 1;
  transform: none;
}
@media (max-width: 1460px) {
  .srail {
    display: none;
  }
}

/* Command palette. Mono, square, no rounding, because it belongs to the same
   drawing as everything else. */
.palette {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: rgba(15, 17, 21, 0.28);
  display: grid;
  place-items: start center;
  padding-top: 14vh;
  backdrop-filter: blur(2px);
}
.palette[hidden] {
  display: none;
}
.palette-box {
  width: min(520px, calc(100vw - 48px));
  background: #fff;
  border: 1px solid var(--ink);
  box-shadow: 0 18px 44px rgba(15, 17, 21, 0.18);
}
.palette-box input {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  padding: 15px 18px;
  font-family: var(--mono);
  font-size: 0.86rem;
  color: var(--ink);
  outline: none;
  background: none;
}
.palette-box ul {
  list-style: none;
  margin: 0;
  padding: 6px 0;
  max-height: 300px;
  overflow-y: auto;
}
.palette-box li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 9px 18px;
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--secondary);
  cursor: pointer;
}
.palette-box li .pn {
  color: var(--muted);
  font-size: 0.66rem;
}
.palette-box li[aria-selected="true"] {
  background: var(--blue-wash);
  color: var(--ink);
  box-shadow: inset 2px 0 0 var(--blue);
}
.palette-foot {
  display: flex;
  gap: 18px;
  padding: 9px 18px;
  border-top: 1px solid var(--hairline);
  font-family: var(--mono);
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
}

/* The colophon. Second footer row, quieter than the first. */
.colophon {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 10px;
  opacity: 0.72;
}

@media print {
  .srail,
  .palette {
    display: none !important;
  }
}
