/* ============================================================
   Components
   Depends on tokens/tokens.css + css/base.css
   ============================================================ */

/* ============================================================
   1. THE SPINE  — signature element
   ------------------------------------------------------------
   A single 1px rail runs down the left edge of the content
   column for the whole page. Every section pins a square node
   to it, every product card taps into it with a short stub.
   The square node is the logo's own counter shape at 7px, so
   the device is derived from the mark rather than applied to it.
   Its job is literal: the division's products are all named
   "…LINK", and the work is connecting operations that were
   previously separate. The rail is that claim, drawn.
   ============================================================ */

.section {
  position: relative;
  padding-block: var(--s-9);
}

/* the rail — top:0/bottom:0 on adjacent sections makes it continuous.
   .hero is on this selector too: the rail has to start at the very top
   of the page, not at the first section below it. */
.section::before,
.hero::before {
  content: "";
  position: absolute;
  inset-block: 0;
  left: max(var(--s-5), (100% - var(--content-max)) / 2 + var(--s-5));
  width: var(--spine-line);
  background: var(--spine-color, var(--rule));
}

.section--no-rail::before {
  display: none;
}

/* the rail fades in at the page's first section and out at the last */
.section--rail-start::before {
  background: linear-gradient(
    to bottom,
    transparent,
    var(--spine-color, var(--rule)) var(--s-9)
  );
}

/* stay solid until the last stretch, then fade — mirrors rail-start.
   A gradient across the whole section would leave a tall closing section
   with a rail that is faint everywhere instead of ending deliberately. */
.section--rail-end::before {
  background: linear-gradient(
    to bottom,
    var(--spine-color, var(--rule)) calc(100% - var(--s-9)),
    transparent
  );
}

.section__inner {
  display: grid;
  grid-template-columns: var(--spine-w) minmax(0, 1fr);
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--s-5);
}

/* spine column: node + section index */
.section__index {
  position: relative;
  padding-left: var(--s-4);
}

.node {
  position: absolute;
  left: calc((var(--node) - var(--spine-line)) / -2);
  top: 0.4em;
  width: var(--node);
  height: var(--node);
  background: var(--accent);
}

.node--hollow {
  background: var(--paper);
  box-shadow: inset 0 0 0 var(--spine-line) var(--rule-strong);
}

.node--lg {
  width: 11px;
  height: 11px;
  /* re-centre on the rail: the base rule offsets by --node (7px) */
  left: calc((11px - var(--spine-line)) / -2);
}

.section__index .t-label {
  display: block;
  padding-top: 0.15em;
}

/* short horizontal stub — taps a card or row into the rail */
.stub {
  position: relative;
}

.stub::before {
  content: "";
  position: absolute;
  top: var(--stub-y, 2.25rem);
  right: 100%;
  width: var(--s-4);
  height: var(--spine-line);
  background: var(--rule);
}

.stub::after {
  content: "";
  position: absolute;
  top: var(--stub-y, 2.25rem);
  right: 100%;
  width: 5px;
  height: 5px;
  margin-top: -2px;
  margin-right: -2px;
  background: var(--rule-strong);
  transition: background var(--dur) var(--ease);
}

.stub:hover::after,
.stub:focus-within::after {
  background: var(--accent);
}

/* a divider that reads as a link, not a rule */
.linkline {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  color: var(--ink-3);
}

.linkline::after {
  content: "";
  flex: 1;
  height: var(--spine-line);
  background: var(--rule);
}

@media (max-width: 47.99em) {
  :root {
    --spine-w: var(--spine-w-sm);
  }

  .section {
    padding-block: var(--s-8);
  }

  .section__index {
    padding-left: var(--s-2);
  }

  .section__index .t-label {
    display: none;
  }

  .stub::before,
  .stub::after {
    display: none;
  }
}

/* ============================================================
   1b. Link mesh — the rail's vocabulary extended into a network
   ------------------------------------------------------------
   A deforming triangular mesh with glowing particles travelling its
   edges. Used on exactly ONE section: the product family. The three
   products are all named "…LINK", so the section that introduces them
   is the one place where the connective idea is the subject rather
   than the frame.

   Rules:
   - one instance per page, never on a page that already has another
     moving element
   - nodes are squares, not circles: same geometry as the rail's node
     and the logo's counter
   - vermilion appears only on the travelling particle, never on the
     static mesh, so the accent still means "this is live"
   - it sits behind everything and must never reduce text contrast
   ============================================================ */

.mesh {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  /* the canvas is decorative; if scripting is off, nothing shows */
  contain: layout paint;

  /* Hold the network at the periphery and let it thin out across the
     middle, where the heading and lead sit. Keeps the reading area
     calm and stops a travelling particle from passing behind a glyph
     at full strength. */
  -webkit-mask-image: radial-gradient(
    118% 96% at 50% 50%,
    rgba(0, 0, 0, 0.16) 0%,
    rgba(0, 0, 0, 0.38) 34%,
    rgba(0, 0, 0, 0.85) 68%,
    #000 100%
  );
  mask-image: radial-gradient(
    118% 96% at 50% 50%,
    rgba(0, 0, 0, 0.16) 0%,
    rgba(0, 0, 0, 0.38) 34%,
    rgba(0, 0, 0, 0.85) 68%,
    #000 100%
  );
}

.mesh canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* the rail and the content both stay above any background layer */
.section:has(.mesh)::before,
.hero:has(.mesh)::before {
  z-index: 1;
}

.mesh ~ .section__inner,
.mesh ~ .hero__inner {
  position: relative;
  z-index: 1;
}

/* ── dark section surface ── */
.section--dark {
  --spine-color: #3a4048;
  background: var(--slate);
  color: var(--on-slate);
}

.section--dark .t-display,
.section--dark .t-h1,
.section--dark .t-h2,
.section--dark .t-h3 {
  color: var(--on-slate);
}

.section--dark .t-lead,
.section--dark .t-muted {
  color: var(--on-slate-2);
}

.section--tint {
  /* --rule on --blueprint is too close in value for a 1px line to read;
     the rail is the signature element and has to stay visible on every
     surface it crosses */
  --spine-color: var(--rule-strong);
  background: var(--blueprint);
}

/* ============================================================
   2. Buttons
   ============================================================ */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  padding: 0.8125rem 1.375rem;
  border: var(--spine-line) solid transparent;
  border-radius: var(--r-2);
  background: transparent;
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-weight: var(--fw-bold);
  line-height: 1.2;
  letter-spacing: 0.01em;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur) var(--ease),
    border-color var(--dur) var(--ease), color var(--dur) var(--ease),
    transform var(--dur-fast) var(--ease);
}

/* the travelling node: the same square as the rail, so an action
   reads as "this connects you onward" rather than a generic arrow */
.btn__node {
  width: 5px;
  height: 5px;
  flex: none;
  background: currentColor;
  transition: transform var(--dur) var(--ease);
}

.btn:hover .btn__node {
  transform: translateX(4px);
}

.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background: var(--accent);
  color: #fff;
}

.btn--primary:hover {
  background: var(--accent-hover);
}

.btn--primary:active {
  background: var(--accent-active);
}

.btn--secondary {
  background: var(--ink);
  color: #fff;
}

.btn--secondary:hover {
  background: var(--slate-2);
}

.btn--ghost {
  border-color: var(--rule-strong);
  color: var(--ink);
}

.btn--ghost:hover {
  border-color: var(--ink);
  background: var(--blueprint);
}

.btn--quiet {
  padding-inline: 0;
  color: var(--ink);
}

.btn--quiet:hover {
  color: var(--accent);
}

.btn--on-dark {
  border-color: rgba(255, 255, 255, 0.28);
  color: #fff;
}

.btn--on-dark:hover {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.08);
}

.btn--sm {
  padding: 0.5rem 0.875rem;
  font-size: var(--fs-xs);
}

.btn--lg {
  padding: 1.0625rem 1.75rem;
  font-size: 1.0625rem;
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.42;
  cursor: not-allowed;
  transform: none;
}

/* ============================================================
   3. Text links
   ============================================================ */

.link {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--rule-strong);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.25em;
  transition: color var(--dur-fast) var(--ease),
    text-decoration-color var(--dur-fast) var(--ease);
}

.link:hover {
  color: var(--accent);
  text-decoration-color: var(--accent);
}

.link--accent {
  color: var(--accent);
  text-decoration-color: var(--vermilion-200);
}

.link-inline-node {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}

/* ============================================================
   4. Cards
   ============================================================ */

.card {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-5);
  border: var(--spine-line) solid var(--rule);
  border-radius: var(--r-2);
  background: var(--paper);
  transition: border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

.card:hover {
  border-color: var(--rule-strong);
  box-shadow: var(--shadow-1);
}

.card--flat:hover {
  border-color: var(--rule);
  box-shadow: none;
}

.card__title {
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: var(--fw-bold);
  line-height: 1.5;
}

.card__body {
  font-size: var(--fs-sm);
  line-height: 1.8;
  color: var(--ink-2);
}

.card__foot {
  margin-top: auto;
  padding-top: var(--s-4);
}

/* product card — carries the product's own colour on one 3px edge only,
   so the family reads as one system with three members */
.card--product {
  border-top: 3px solid var(--product, var(--rule-strong));
  padding-top: calc(var(--s-5) - 2px);
}

.card--product .card__meta {
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
}

.product-name {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: var(--fw-black);
  letter-spacing: -0.01em;
}

.product-dot {
  width: var(--node);
  height: var(--node);
  flex: none;
  background: var(--product, var(--ci-vermilion));
}

/* ============================================================
   4b. Product block — the product page's own layout
   ------------------------------------------------------------
   One product per section, set as two columns: what it is on the
   left, what it does on the right. The page used to put a narrow
   card on the left and leave the rest empty, which is what made it
   feel thin — the fix is to use the width for content, not texture.

   No box. The section's own surface separates one product from the
   next, and a single hairline divides the two columns.
   ============================================================ */

.product-block {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  gap: var(--s-8);
  align-items: start;
}

.product-block__name {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.6vw, 2.125rem);
  font-weight: var(--fw-black);
  line-height: 1.1;
  letter-spacing: -0.015em;
}

/* the product's colour appears once, as a short rule under its name.
   No coloured panels, no coloured type — the family still reads as
   one system with three members. */
.product-block__rule {
  width: 2.75rem;
  height: 2px;
  margin-top: var(--s-4);
  background: var(--product, var(--rule-strong));
}

.product-block__kind {
  display: block;
  margin-top: var(--s-4);
}

.product-block__body {
  margin-top: var(--s-3);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-2);
  max-width: 26em;
}

.product-block__link {
  margin-top: var(--s-5);
}

/* capability list — structured like the spec rows, so it reads as
   data rather than as a bulleted sales list */
.product-block__caps {
  padding-left: var(--s-7);
  /* --spine-color follows the surface: --rule on white, --rule-strong on
     the tint. Reusing it keeps this hairline as visible as the rail on
     every background. */
  border-left: var(--spine-line) solid var(--spine-color, var(--rule));
}

.caps__head {
  display: block;
  margin-bottom: var(--s-3);
}

.caps {
  border-top: var(--spine-line) solid var(--rule);
}

.caps li {
  padding-block: 0.6875rem;
  border-bottom: var(--spine-line) solid var(--rule);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--ink-2);
}

@media (max-width: 55.99em) {
  .product-block {
    grid-template-columns: 1fr;
    gap: var(--s-6);
  }

  .product-block__caps {
    padding-left: 0;
    border-left: 0;
  }
}

/* ============================================================
   5. Badges & chips
   ============================================================ */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 0.3125rem 0.5625rem;
  border: var(--spine-line) solid var(--rule);
  border-radius: var(--r-1);
  background: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--fw-medium);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--ink-2);
}

.badge--accent {
  border-color: var(--vermilion-200);
  background: var(--vermilion-050);
  color: var(--vermilion-700);
}

.badge--solid {
  border-color: var(--ink);
  background: var(--ink);
  color: #fff;
}

.badge--on-dark {
  border-color: rgba(255, 255, 255, 0.24);
  background: transparent;
  color: var(--on-slate-2);
}

/* NOTE: there is deliberately no .tag component. Tags existed only to list
   the technology stack, and the stack is not shown anywhere on this site —
   what a client is deciding on is what we can do, not what we build it with. */

/* ============================================================
   6. Form controls
   ============================================================ */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.field__label {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-2);
}

.field__req {
  color: var(--accent);
  letter-spacing: 0;
}

.input,
.textarea,
.select {
  width: 100%;
  padding: 0.75rem 0.875rem;
  border: var(--spine-line) solid var(--rule-strong);
  border-radius: var(--r-2);
  background: var(--paper);
  font-size: var(--fs-body);
  line-height: 1.5;
  transition: border-color var(--dur-fast) var(--ease),
    box-shadow var(--dur-fast) var(--ease);
}

.input::placeholder,
.textarea::placeholder {
  color: var(--ink-4);
}

.input:hover,
.textarea:hover,
.select:hover {
  border-color: var(--ink-3);
}

.input:focus,
.textarea:focus,
.select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--vermilion-100);
}

.textarea {
  min-height: 8rem;
  resize: vertical;
}

.select {
  appearance: none;
  padding-right: 2.25rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-2) 50%),
    linear-gradient(135deg, var(--ink-2) 50%, transparent 50%);
  background-position: calc(100% - 1.125rem) 55%, calc(100% - 0.875rem) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.field__help {
  font-size: var(--fs-xs);
  line-height: 1.6;
  color: var(--ink-3);
}

.field--invalid .input,
.field--invalid .textarea,
.field--invalid .select {
  border-color: var(--danger);
}

.field__error {
  display: flex;
  gap: var(--s-2);
  font-size: var(--fs-xs);
  line-height: 1.6;
  color: var(--danger);
}

.check {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  font-size: var(--fs-sm);
  line-height: 1.6;
  cursor: pointer;
}

.check input {
  width: 1.125rem;
  height: 1.125rem;
  margin: 0.2rem 0 0;
  flex: none;
  accent-color: var(--accent);
}

/* ============================================================
   7. Spec list — key/value data, mono keys
   ============================================================ */

.spec {
  border-top: var(--spine-line) solid var(--rule);
}

.spec__row {
  display: grid;
  grid-template-columns: minmax(9rem, 22%) 1fr;
  gap: var(--s-4);
  padding-block: var(--s-4);
  border-bottom: var(--spine-line) solid var(--rule);
}

.spec__key {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  line-height: 1.9;
  color: var(--ink-3);
}

.spec__val {
  font-size: var(--fs-sm);
  line-height: 1.8;
}

@media (max-width: 39.99em) {
  .spec__row {
    grid-template-columns: 1fr;
    gap: var(--s-2);
  }
}

/* ============================================================
   8. Header
   ============================================================ */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: blur(12px);
  border-bottom: var(--spine-line) solid var(--rule);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--s-4) var(--s-5);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex: none;
}

.brand__logo {
  height: 1.75rem;
  width: auto;
}

.brand__division {
  padding-left: var(--s-3);
  border-left: var(--spine-line) solid var(--rule);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-3);
}

.nav {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  margin-left: auto;
}

.nav__link {
  position: relative;
  padding-block: var(--s-2);
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-weight: var(--fw-medium);
  color: var(--ink-2);
  transition: color var(--dur-fast) var(--ease);
}

.nav__link:hover {
  color: var(--ink);
}

/* active state uses the node, not an underline — same vocabulary as the rail */
.nav__link[aria-current="page"] {
  color: var(--ink);
  font-weight: var(--fw-bold);
}

.nav__link[aria-current="page"]::before {
  content: "";
  position: absolute;
  top: -0.125rem;
  left: 50%;
  width: 5px;
  height: 5px;
  margin-left: -2.5px;
  background: var(--accent);
}

@media (max-width: 55.99em) {
  .nav {
    display: none;
  }
}

.nav-toggle {
  display: none;
  flex: none;
  margin-left: auto;
  padding: var(--s-2);
  border: var(--spine-line) solid var(--rule-strong);
  border-radius: var(--r-2);
  background: transparent;
  cursor: pointer;
}

@media (max-width: 55.99em) {
  .nav-toggle {
    display: block;
  }

  /* the lockup has to give way to the toggle: at these widths the
     wordmark alone is enough to identify the site */
  .site-header__inner {
    gap: var(--s-3);
    padding: var(--s-3) var(--s-4);
  }

  .brand__logo {
    height: 1.5rem;
  }
}

@media (max-width: 29.99em) {
  .brand__division {
    display: none;
  }
}

/* ============================================================
   9. Hero
   ============================================================ */

.hero {
  position: relative;
  padding-block: var(--s-10) var(--s-9);
}

.hero__inner {
  display: grid;
  grid-template-columns: var(--spine-w) minmax(0, 1fr);
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--s-5);
}

.hero__title {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  font-weight: var(--fw-black);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-display);
  text-wrap: balance;
  color: var(--ink);
}

/* the linked phrase: the rail motif surfacing inside the sentence */
.linked {
  position: relative;
  white-space: nowrap;
}

.linked::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.12em;
  height: 3px;
  background: var(--accent);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-6);
}

@media (max-width: 47.99em) {
  .hero {
    padding-block: var(--s-8) var(--s-7);
  }
}

/* ============================================================
   10. Steps — a real sequence, so it is numbered
   ============================================================ */

.steps {
  display: grid;
  gap: 0;
}

.step {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: var(--s-4);
  padding-block: var(--s-5);
  border-top: var(--spine-line) solid var(--rule);
}

.step:last-child {
  border-bottom: var(--spine-line) solid var(--rule);
}

.step__n {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--ci-vermilion);
}

.step__title {
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: var(--fw-bold);
  line-height: 1.5;
}

.step__body {
  margin-top: var(--s-2);
  font-size: var(--fs-sm);
  line-height: 1.8;
  color: var(--ink-2);
}

/* ============================================================
   11. CTA band
   ============================================================ */

.cta {
  background: var(--slate);
  color: var(--on-slate);
}

.cta__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s-5);
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--s-8) var(--s-5);
}

/* ============================================================
   12. Footer
   ============================================================ */

.site-footer {
  background: var(--slate);
  color: var(--on-slate-2);
  border-top: 3px solid var(--accent);
}

.site-footer__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr));
  gap: var(--s-6);
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--s-8) var(--s-5) var(--s-6);
}

.site-footer__logo {
  height: 1.625rem;
  width: auto;
}

.footer-col__head {
  margin-bottom: var(--s-4);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: #fff;
}

.footer-col li + li {
  margin-top: var(--s-3);
}

.footer-col a {
  font-size: var(--fs-sm);
  color: var(--on-slate-2);
  transition: color var(--dur-fast) var(--ease);
}

.footer-col a:hover {
  color: #fff;
}

.site-footer__base {
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--s-4) var(--s-5) var(--s-6);
  border-top: var(--spine-line) solid rgba(255, 255, 255, 0.14);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: 0.08em;
  color: #6f757d;
}

@media (max-width: 55.99em) {
  .site-footer__inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 39.99em) {
  .site-footer__inner {
    grid-template-columns: 1fr;
    gap: var(--s-5);
  }
}
