/* ==========================================================================
   Peristyle - "living stone" theme
   Roman + Hindu fusion, no religious icons, muted aged palette.
   See skills/peristyle-style-guide/SKILL.md for the rules this file obeys.
   ========================================================================== */

:root {
  --ink: #221d18;
  --ink-2: #2c2620;
  --ink-soft: #3a322a;
  --paper: #f4efe6;
  --paper-warm: #e9e0d1;
  --paper-deep: #ded2be;
  --terracotta: #b5623a;
  --terracotta-deep: #96502e;
  --ochre: #c08a3e;
  --ochre-deep: #8a5a1e;
  --indigo: #2f4a63;
  --verdigris: #4c7a6b;
  --verdigris-deep: #3b6154;
  --sand: #cbb79a;
  --sand-deep: #6f5c44;
  --olive: #5f6438;
  --line: #d8cdba;
  --line-dark: rgba(203, 183, 154, 0.22);

  --serif: 'Cormorant Garamond', 'Iowan Old Style', Georgia, serif;
  --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'DM Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --shell: 1240px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --band: clamp(3.5rem, 7vw, 6.5rem);
  --radius: 4px;

  --shadow-soft: 0 24px 60px rgba(34, 29, 24, 0.14);
  --shadow-lift: 0 30px 80px rgba(34, 29, 24, 0.24);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--sans);
  background: var(--paper);
  color: var(--ink);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; }
/* The <picture> wrappers added for WebP must not change the box tree: with
   display: contents the <img> stays the direct child of .hero-media,
   .image-band, .split-media and the rest, so every existing selector still
   matches and the layout is unchanged. */
picture { display: contents; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--terracotta); color: #fff; }

.shell { max-width: var(--shell); margin: 0 auto; padding-inline: var(--gutter); }
.section { scroll-margin-top: 5.5rem; }

/* --------------------------------------------------------------- typography */

.kicker {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--terracotta);
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
}
.kicker::before {
  content: "";
  width: 26px;
  height: 1px;
  background: currentColor;
  opacity: 0.7;
}
.kicker.on-dark { color: var(--ochre); }

.display {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(2.5rem, 5.6vw, 4.9rem);
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(2rem, 3.6vw, 3.2rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.lede {
  font-size: clamp(1.02rem, 1.35vw, 1.18rem);
  color: var(--ink-soft);
  max-width: 42rem;
  line-height: 1.7;
}
.on-dark .lede, .band-dark .lede, .band-ink-soft .lede { color: rgba(244, 239, 230, 0.78); }
.on-dark .title, .band-dark .title { color: var(--paper); }

.rule {
  height: 1px;
  background: var(--line);
  border: 0;
}
.band-dark .rule { background: var(--line-dark); }

/* ------------------------------------------------------------------ buttons */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 50px;
  padding: 0.9rem 1.6rem;
  border-radius: 999px;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  font-size: 0.94rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  transition: transform 0.2s ease, background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.btn:hover { transform: translateY(-2px); background: var(--terracotta-deep); border-color: var(--terracotta-deep); }
.btn-ghost {
  background: transparent;
  color: var(--ink);
  border-color: rgba(34, 29, 24, 0.28);
}
.btn-ghost:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn-light { background: var(--paper); color: var(--ink); border-color: var(--paper); }
/* ochre + #fff measured 3.02:1 - below WCAG AA for normal text.
   terracotta-deep + paper measures 5.26:1. */
.btn-light:hover { background: var(--terracotta-deep); color: var(--paper); border-color: var(--terracotta-deep); }
.btn-outline-light { background: transparent; color: var(--paper); border-color: rgba(244, 239, 230, 0.45); }
.btn-outline { background: transparent; color: var(--ink); border-color: var(--line-strong, var(--line)); }
.btn-outline:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.btn-outline-light:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.btn-sm { min-height: 42px; padding: 0.65rem 1.15rem; font-size: 0.88rem; }

/* ---------------------------------------------------------------------- nav */

.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(20, 17, 14, 0.72);
  backdrop-filter: blur(18px) saturate(1.1);
  -webkit-backdrop-filter: blur(18px) saturate(1.1);
  border-bottom: 1px solid rgba(203, 183, 154, 0.18);
}
.nav-inner {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0.85rem var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
}
.brand { display: inline-flex; align-items: center; gap: 0.85rem; }
/* The Peristyle trademark, in its reversed (light-on-dark) variant.
   peristyle-mark-inverted.png is a pixel-exact colour inversion of the
   registered mark dev/static/img/peristyle-mark-transparent.png: the navy
   ink becomes bone (--paper), the interior becomes transparent. The
   geometry is untouched - only the colour changes - so the mark reads
   directly against the dark nav with no chip, card or backing plate.
   The PNG is generated with --bleed, so its transparent pixels carry the
   bone colour underneath rather than black; without that, a downscaling
   filter interpolating non-premultiplied RGBA drags black into the edges
   and the mark picks up a dark halo against the bar.
   The unreversed mark stays in the repo and is used on light backgrounds
   (see .logo-plate on the About page). */
.brand-mark {
  /* 120px wide: the artwork is line art, and below ~100px the strokes
     merge into a grey smear when the browser downsamples it. */
  width: 120px;
  height: 65px;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}
.brand-mark img { width: 100%; height: 100%; object-fit: contain; }
.brand-name {
  font-family: var(--serif);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--paper);
}
.brand-sub {
  display: block;
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ochre);
  margin-top: 3px;
}
.nav-links { display: flex; align-items: center; gap: 1.6rem; }
/* NOTE: :not(.btn) is load-bearing. A bare ".nav-links a" rule has
   specificity (0,1,1) and beats ".btn-light" (0,1,0), so it repainted the
   nav CTA's text in bone while the button kept its paper background - a
   measured contrast ratio of 1.0:1, i.e. invisible label. Excluding .btn
   from the link rule lets .btn-light own the button's colour. */
.nav-links a:not(.btn) {
  font-size: 0.9rem;
  color: rgba(244, 239, 230, 0.72);
  transition: color 0.18s ease;
}
.nav-links a:not(.btn):hover, .nav-links a:not(.btn).active { color: var(--paper); }
.nav-cta { padding: 0.6rem 1.15rem; min-height: 40px; font-size: 0.86rem; }

.preview-bar {
  background: var(--terracotta);
  color: #fff;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  padding: 0.55rem var(--gutter);
}
.preview-bar a { text-decoration: underline; text-underline-offset: 3px; }

/* --------------------------------------------------------------------- hero */

.hero {
  position: relative;
  min-height: min(88vh, 860px);
  /* Column, not row. The hero holds two blocks - the copy and the meta
     strip - and as a row they shared one line: the copy was squeezed to
     ~406px of text column and the meta strip ran off the right edge. */
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: stretch;
  overflow: hidden;
  background: var(--ink);
}
.hero-media { position: absolute; inset: 0; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; }
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(20, 17, 14, 0.72) 0%, rgba(20, 17, 14, 0.25) 34%, rgba(20, 17, 14, 0.88) 100%),
    linear-gradient(90deg, rgba(20, 17, 14, 0.82) 0%, rgba(20, 17, 14, 0.15) 58%);
}
.hero-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--shell);
  margin: 0 auto;
  padding: clamp(4rem, 9vw, 7.5rem) var(--gutter) clamp(3rem, 6vw, 5rem);
  color: var(--paper);
}
.hero-copy { max-width: 46rem; }
.hero .display { color: var(--paper); }
.hero-sub {
  margin-top: 1.5rem;
  max-width: 38rem;
  font-size: clamp(1.05rem, 1.4vw, 1.22rem);
  color: rgba(244, 239, 230, 0.82);
}
.hero-actions { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-top: 2.4rem; }
.hero-meta {
  position: relative;
  z-index: 2;
  /* flex: 0 0 100% keeps this strip on its own line. As a plain flex item
     it shrank to fit its content, which pushed the whole strip off the
     right edge on a 320px phone and clipped the last item. */
  flex: 0 0 100%;
  width: 100%;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--gutter) 2.2rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem 2.6rem;
  color: rgba(244, 239, 230, 0.62);
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* ------------------------------------------------------------------- bands */

.band { padding: var(--band) 0; }
.band-paper { background: var(--paper); }
.band-warm { background: var(--paper-warm); }
.band-dark { background: var(--ink); color: var(--paper); }
.band-dark .kicker { color: var(--ochre); }
.band-ink-soft { background: var(--ink-2); color: var(--paper); }
.band-ink-soft .kicker { color: var(--ochre); }

.band-head { max-width: 46rem; margin-bottom: clamp(2.5rem, 4vw, 3.6rem); }
.band-head .title { margin-top: 1rem; }
.band-head .lede { margin-top: 1.1rem; }

/* full-bleed image band */
.image-band { position: relative; overflow: hidden; }
.image-band img { width: 100%; height: clamp(320px, 52vw, 620px); object-fit: cover; }
.image-band figcaption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: clamp(2.5rem, 5vw, 4rem) var(--gutter);
  background: linear-gradient(180deg, rgba(20, 17, 14, 0) 0%, rgba(20, 17, 14, 0.55) 18%, rgba(20, 17, 14, 0.88) 40%);
  color: var(--paper);
}
.image-band figcaption .title { color: var(--paper); max-width: 30ch; }
.image-band figcaption .lede { color: rgba(244, 239, 230, 0.78); margin-top: 0.9rem; }

/* ------------------------------------------------------------------- split */

.split {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
.split.flip .split-media { order: -1; }
.split-media { position: relative; }
.split-media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius);
  box-shadow: var(--shadow-soft);
}
.split-media.tall img { aspect-ratio: 3 / 4; }

/* The trademark shown as a plaque: the logo is reproduced at full aspect on a
   paper plate, never cropped and never recoloured. */
.logo-plate {
  background: var(--paper);
  border-radius: var(--radius);
  box-shadow: var(--shadow-soft);
  display: grid;
  place-items: center;
  padding: 2.5rem;
}
.logo-plate img {
  width: 100%;
  aspect-ratio: auto;
  object-fit: contain;
  box-shadow: none;
}
.split-copy .title { margin-top: 1rem; }
.split-copy .lede { margin-top: 1.2rem; }
.split-copy .btn { margin-top: 2rem; }

/* ------------------------------------------------------------------- cards */

.grid { display: grid; gap: 1.4rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

/* The self-hosting hardware band holds four cards. auto-fit would leave a
   lone card stranded on its own row, so the band uses a fixed two-column
   grid (2x2) that collapses to a single column on narrow screens. */
.grid-cards-2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 860px) {
  .grid-cards-2 { grid-template-columns: 1fr; }
}

/* The team section is a swipeable rail of seven role cards. A phone user
   swipes natively; a desktop user gets arrows and a progress bar. The next
   card is always partly visible, which is the signal that there are more. */
.rail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.rail-hint {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.rail-nav { display: flex; gap: 0.5rem; }
.rail-btn {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;
}
.rail-btn:hover:not(:disabled) { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.rail-btn:disabled { opacity: 0.3; cursor: default; }
.rail-btn:focus-visible { outline: 2px solid var(--terracotta-deep); outline-offset: 2px; }

.team-rail {
  display: flex;
  gap: 1.4rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  margin-top: 1.4rem;
  padding-block: 0.4rem 0.6rem;
}
.team-rail::-webkit-scrollbar { display: none; }
.team-rail > .card {
  flex: 0 0 82%;
  scroll-snap-align: start;
}
@media (max-width: 680px) {
  /* Full-bleed so a card can run off the screen edge, with the snap point
     pulled back to the text gutter so a snapped card still lines up. */
  .team-rail {
    margin-inline: calc(-1 * var(--gutter));
    padding-inline: var(--gutter);
    scroll-padding-inline-start: var(--gutter);
  }
}
@media (min-width: 681px) and (max-width: 1100px) {
  .team-rail > .card { flex: 0 0 calc((100% - 1.4rem) / 2); }
}
@media (min-width: 1101px) {
  .team-rail > .card { flex: 0 0 calc((100% - 2.8rem) / 3); }
}
.team-rail:focus-visible { outline: 2px solid var(--terracotta-deep); outline-offset: 4px; }

.rail-progress {
  position: relative;
  height: 3px;
  margin-top: 0.6rem;
  background: var(--line);
  border-radius: 3px;
}
.rail-progress i {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 30%;
  background: var(--terracotta-deep);
  border-radius: 3px;
}

/* The offer above the roster: the free templates are the catalogue, the
   custom team member is the work that follows it. */
.custom-note {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: clamp(1.4rem, 3vw, 2.2rem) clamp(1.4rem, 3vw, 2.4rem);
  background: var(--paper-warm);
  border-left: 3px solid var(--terracotta);
  border-radius: var(--radius);
}
.custom-note-title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.3rem, 2.4vw, 1.75rem);
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin-top: 0.7rem;
}
.custom-note-text {
  color: var(--ink-soft);
  font-size: 0.95rem;
  max-width: 44ch;
  margin-top: 0.5rem;
}
.custom-note .btn { flex: 0 0 auto; }
@media (max-width: 620px) {
  .custom-note .btn { width: 100%; justify-content: center; }
}
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.band-dark .card, .band-ink-soft .card {
  background: rgba(244, 239, 230, 0.05);
  border-color: var(--line-dark);
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lift); }
.card-media { position: relative; aspect-ratio: 16 / 10; overflow: hidden; }
.card-media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; }
.card:hover .card-media img { transform: scale(1.04); }
.card-body { padding: 1.5rem 1.6rem 1.7rem; display: flex; flex-direction: column; gap: 0.6rem; flex: 1; }
.card-tag {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--terracotta);
}
.card h3 { font-family: var(--serif); font-size: 1.5rem; font-weight: 600; line-height: 1.15; letter-spacing: -0.01em; }
.card p { color: var(--ink-soft); font-size: 0.95rem; }
.band-dark .card p, .band-ink-soft .card p { color: rgba(244, 239, 230, 0.72); }
.card-foot {
  margin-top: auto;
  padding-top: 1rem;
  border-top: 1px dashed var(--line);
  font-size: 0.88rem;
}
.band-dark .card-foot, .band-ink-soft .card-foot { border-color: var(--line-dark); color: rgba(244, 239, 230, 0.6); }
.card-foot a { color: var(--terracotta-deep); font-weight: 500; }
.card-foot a:hover { text-decoration: underline; }
.card-foot strong {
  display: block;
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: 0.3rem;
}

/* Card role accents. Every one of these is measured against the card
   background (--paper) at >= 4.5:1, because the role label is 0.66rem
   uppercase mono - small text, so it needs the AA small-text ratio.
   Measured 2026-10-24: terracotta-deep 5.26, verdigris-deep 6.06,
   indigo 8.04, ink 14.59, ochre-deep 5.15, sand-deep 5.57, olive 5.45. */
.accent-sales { color: var(--terracotta-deep); }
.accent-procurement { color: var(--verdigris-deep); }
.accent-bookkeeping { color: var(--indigo); }
.accent-sysadmin { color: var(--ink); }
.accent-software { color: var(--ochre-deep); }
.accent-auditor { color: var(--sand-deep); }
.accent-pm { color: var(--olive); }

/* --------------------------------------------------------------- stat band */

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1.4rem;
}
.stat {
  padding: 1.6rem 1.7rem;
  border-left: 2px solid var(--terracotta);
  background: rgba(244, 239, 230, 0.04);
}
.band-paper .stat, .band-warm .stat { background: rgba(255, 255, 255, 0.5); }
.stat-num {
  font-family: var(--serif);
  font-size: 2.4rem;
  font-weight: 600;
  line-height: 1;
  color: var(--paper);
}
.band-paper .stat-num, .band-warm .stat-num { color: var(--ink); }
.stat-label {
  margin-top: 0.6rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(244, 239, 230, 0.62);
}
.band-paper .stat-label, .band-warm .stat-label { color: var(--ink-soft); }

/* ------------------------------------------------------------------ steps */

.steps { counter-reset: step; display: grid; gap: 0; }
.step {
  display: grid;
  grid-template-columns: 140px minmax(0, 1fr);
  gap: 1.5rem;
  padding: 2.2rem 0;
  border-top: 1px solid var(--line);
  align-items: start;
}
.band-dark .step { border-color: var(--line-dark); }
.step:last-child { border-bottom: 1px solid var(--line); }
.band-dark .step:last-child { border-color: var(--line-dark); }
.step-num {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--terracotta);
  padding-top: 0.45rem;
}
.band-dark .step-num { color: var(--ochre); }
.step h3 { font-family: var(--serif); font-size: 1.7rem; font-weight: 600; margin-bottom: 0.5rem; }
.step p { color: var(--ink-soft); max-width: 46rem; }
.band-dark .step p { color: rgba(244, 239, 230, 0.72); }

/* A step may cite the article that carries its date. The link has to
   look like a link on the warm band, and meet the 4.5:1 text contrast
   that --terracotta-deep gives on --paper-warm. */
.step p a { color: var(--terracotta-deep); text-decoration: underline; text-underline-offset: 3px; }
.step p a:hover { text-decoration-thickness: 2px; }
.band-dark .step p a { color: var(--ochre); }

/* ---------------------------------------------------------------- pricing */

.price-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.4rem;
  align-items: stretch;
}
.price-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 2rem 1.9rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.price-card.featured {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
  box-shadow: var(--shadow-lift);
}
.price-flag {
  position: absolute;
  top: -11px;
  left: 1.9rem;
  background: var(--ochre);
  color: #241d10;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 0.35rem 0.8rem;
  border-radius: 999px;
}
.price-name {
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--terracotta);
}
.price-card.featured .price-name { color: var(--ochre); }
.price-amount {
  font-family: var(--serif);
  font-size: clamp(3rem, 5vw, 4rem);
  font-weight: 600;
  line-height: 1;
  margin: 1rem 0 0.2rem;
  letter-spacing: -0.02em;
}
.price-unit { font-size: 0.85rem; color: var(--ink-soft); }
.price-card.featured .price-unit { color: rgba(244, 239, 230, 0.7); }
.price-list { list-style: none; margin: 1.6rem 0 0; padding: 1.4rem 0 0; border-top: 1px solid var(--line); }
.price-card.featured .price-list { border-color: var(--line-dark); }
.price-list li {
  position: relative;
  padding: 0.35rem 0 0.35rem 1.4rem;
  font-size: 0.92rem;
  color: var(--ink-soft);
}
.price-card.featured .price-list li { color: rgba(244, 239, 230, 0.78); }
.price-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 7px;
  height: 7px;
  background: var(--terracotta);
  transform: rotate(45deg);
}
.price-note {
  margin-top: auto;
  padding-top: 1.5rem;
  font-size: 0.88rem;
  color: var(--ink-soft);
}
.price-card.featured .price-note { color: rgba(244, 239, 230, 0.8); }

/* Every pricing band routes to a quote (2026-10-31). No card is a
   checkout: the published figures are "from" prices, and the only action
   on any band is "Get a Quote". The CTA sits inside the card, below the
   note, so the price and the action read as one thing. */
.price-cta {
  margin-top: 1.1rem;
  align-self: flex-start;
}
.card .price-cta {
  margin-top: 1.1rem;
  align-self: flex-start;
}
.price-card.featured .price-cta {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--paper);
}
.price-card.featured .price-cta:hover {
  background: var(--terracotta-deep);
  color: var(--paper);
  border-color: var(--terracotta-deep);
}

.link-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.4rem 1.6rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: transform 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
.link-card:hover { transform: translateY(-2px); border-color: var(--terracotta); }
.link-card .name { font-family: var(--serif); font-size: 1.3rem; font-weight: 600; }
.link-card .price {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--verdigris);
  white-space: nowrap;
}
.link-card .desc { font-size: 0.88rem; color: var(--ink-soft); margin-top: 0.25rem; }

.quote-card {
  padding: clamp(2rem, 4vw, 3.2rem);
  background: var(--paper-warm);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
  gap: 2rem;
  align-items: center;
}
.quote-card .title { margin-top: 0.9rem; }
.quote-actions { display: flex; flex-wrap: wrap; gap: 0.8rem; justify-content: flex-end; }

/* ------------------------------------------------------------------ forms */

.field { display: flex; flex-direction: column; gap: 0.45rem; margin-bottom: 1.2rem; }
.field label {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.field input, .field select, .field textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  background: #fbf8f2;
  border: 1px solid var(--line);
  border-radius: 2px;
  font-size: 0.95rem;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--terracotta);
  box-shadow: 0 0 0 3px rgba(181, 98, 58, 0.14);
}
.field textarea { min-height: 150px; resize: vertical; }
.form-note { font-size: 0.82rem; color: var(--ink-soft); margin-top: 0.8rem; }
.form-ok {
  background: rgba(76, 122, 107, 0.12);
  border: 1px solid rgba(76, 122, 107, 0.45);
  color: #2f5a4c;
  padding: 0.9rem 1.1rem;
  border-radius: 2px;
  margin-bottom: 1.4rem;
  font-size: 0.92rem;
}
.form-err {
  background: rgba(181, 98, 58, 0.12);
  border: 1px solid rgba(181, 98, 58, 0.5);
  color: #8a4527;
  padding: 0.9rem 1.1rem;
  border-radius: 2px;
  margin-bottom: 1.4rem;
  font-size: 0.92rem;
}
.contact-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.72fr); gap: clamp(2rem, 5vw, 4rem); align-items: start; }
.contact-panel {
  background: var(--ink);
  color: var(--paper);
  padding: clamp(1.8rem, 3vw, 2.4rem);
  border-radius: var(--radius);
}
.contact-panel h3 { font-family: var(--serif); font-size: 1.6rem; font-weight: 600; margin-bottom: 1.1rem; }
.contact-list { list-style: none; display: grid; gap: 1rem; }
.contact-list li { font-size: 0.92rem; color: rgba(244, 239, 230, 0.78); }
.contact-list strong {
  display: block;
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: 0.2rem;
}
.contact-list a:hover { color: var(--paper); text-decoration: underline; text-underline-offset: 3px; }


/* ------------------------------------------------------------------- news */

/* The newsfeed is a standing record of LinkedIn posts. Each item is a
   two-column card: the post image on the left, the text on the right, and a
   single-column stack on phones. */
.news-list { display: grid; gap: 1.6rem; }
.news-item {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(1.4rem, 3vw, 2.4rem);
  align-items: start;
  padding: 1.6rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: transform 0.2s ease, border-color 0.2s ease;
}
.news-item:hover { transform: translateY(-2px); border-color: var(--terracotta); }
.news-item-media {
  display: block;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--paper-warm);
}
.news-item-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.news-item-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.news-item-kind { color: var(--terracotta); }
.news-item-title {
  font-family: var(--serif);
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.015em;
  margin-top: 0.8rem;
}
.news-item-summary { margin-top: 0.8rem; color: var(--ink-soft); max-width: 46rem; }
.news-item-points {
  list-style: none;
  margin-top: 1.1rem;
  display: grid;
  gap: 0.4rem;
  max-width: 46rem;
}
.news-item-points li {
  position: relative;
  padding-left: 1.4rem;
  font-size: 0.92rem;
  color: var(--ink-soft);
}
.news-item-points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.66em;
  width: 7px;
  height: 7px;
  background: var(--terracotta);
  transform: rotate(45deg);
}
.news-item-note {
  margin-top: 1.1rem;
  padding: 0.9rem 1.1rem;
  border-left: 2px solid var(--ochre);
  background: rgba(255, 255, 255, 0.5);
  font-size: 0.9rem;
  color: var(--ink-soft);
  max-width: 46rem;
}
.news-item-actions { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 1.6rem; }

@media (max-width: 860px) {
  .news-item { grid-template-columns: 1fr; padding: 1.2rem; }
  .news-item-media img { max-height: 320px; }
}

/* ------------------------------------------------------------------ footer */

.footer { background: var(--ink); color: rgba(244, 239, 230, 0.7); padding: clamp(3rem, 6vw, 4.5rem) 0 2.5rem; }
.footer-top { display: grid; grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 0.8fr)); gap: 2.5rem; }
.footer .brand-name { color: var(--paper); }
.footer h4 {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ochre);
  margin-bottom: 1rem;
}
.footer-links { list-style: none; display: grid; gap: 0.6rem; }
.footer-links a { font-size: 0.9rem; }
.footer-links a:hover { color: var(--paper); }
.footer-note { margin-top: 0.9rem; font-size: 0.88rem; max-width: 34rem; color: rgba(244, 239, 230, 0.55); }
.footer-bottom {
  margin-top: 3rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--line-dark);
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem 2rem;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(244, 239, 230, 0.45);
}

/* --------------------------------------------------------------- utilities */

.mt-1 { margin-top: 1rem; }
.mt-2 { margin-top: 2rem; }
.mt-3 { margin-top: 3rem; }
.mt-4 { margin-top: 4rem; }
.center { text-align: center; }
.center .lede { margin-inline: auto; }
.center .kicker { justify-content: center; }
.tag-row { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.6rem; }
.tag {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink-soft);
}
.band-dark .tag, .band-ink-soft .tag { border-color: var(--line-dark); color: rgba(244, 239, 230, 0.7); }

/* Small screens: the nav used to run off the right edge below ~560px - the
   brand plus four links plus the CTA did not fit, so the CTA was clipped by
   the page's overflow guard and a phone user could not see it at all.
   Below 560px the wordmark goes, the mark shrinks to its minimum legible
   size, and the CTA shortens to "Start" (the accessible name stays the full
   "Start a conversation"). */
.nav-cta .cta-short { display: none; }
@media (max-width: 560px) {
  .brand-text { display: none; }
  .brand-mark { width: 60px; height: 33px; }
  .nav-inner { padding-block: 0.7rem; gap: 0.9rem; }
  .nav-links { gap: 0.9rem; }
  .nav-links a:not(.btn) { font-size: 0.86rem; }
  .nav-cta .cta-long { display: none; }
  .nav-cta .cta-short { display: inline; }
  .nav-cta { padding: 0.5rem 0.95rem; min-height: 38px; font-size: 0.82rem; }
}
@media (max-width: 380px) {
  .nav-links { gap: 0.7rem; }
  .nav-links a:not(.btn) { font-size: 0.8rem; }
  .nav-cta { padding: 0.45rem 0.8rem; font-size: 0.78rem; }
}


/* ------------------------------------------------------------- responsive */

@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; }
  .split.flip .split-media { order: 0; }
  .contact-grid { grid-template-columns: 1fr; }
  .quote-card { grid-template-columns: 1fr; }
  .quote-actions { justify-content: flex-start; }
  .footer-top { grid-template-columns: 1fr; }
  .step { grid-template-columns: 1fr; gap: 0.5rem; }
}

@media (max-width: 720px) {
  .nav-links { gap: 1rem; font-size: 0.85rem; }
  .brand-name { font-size: 1.3rem; }
  .hero { min-height: 76vh; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  html { scroll-behavior: auto; }
}

/* Five nav items (About, Pricing, Blog, News, CTA) plus the brand mark no
   longer fit at 320px: the nav-inner scrolled to 355px and the CTA was
   clipped off the right edge again. This block tightens the spacing
   further and trims the gutter so the CTA stays inside the viewport. */
@media (max-width: 420px) {
  .nav-inner { padding-inline: 12px; gap: 0.6rem; }
  .nav-links { gap: 0.55rem; }
  .nav-links a:not(.btn) { font-size: 0.78rem; }
  .nav-cta { padding: 0.4rem 0.6rem; font-size: 0.76rem; }
  .brand-mark { width: 54px; height: 30px; }
}

/* ------------------------------------------------------------------ ledger */
/* A data table for the About page: the public repositories and the privacy
   profiles. Built on a real <table> so screen readers get the row/column
   relationships, styled as a quiet ruled ledger rather than a boxed grid.
   Measured: ink-soft on paper 10.98:1, on ink-2 6.36:1 at 62% over ink-2.
   The ochre licence accent is 5.15:1 on paper and 4.94:1 on ink-2. */
.ledger {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}
.ledger thead th {
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 0 1.2rem 0.8rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: bottom;
}
.ledger tbody th,
.ledger tbody td {
  padding: 1.15rem 1.2rem 1.15rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  font-size: 0.95rem;
  font-weight: 400;
  color: var(--ink-soft);
}
.ledger tbody th {
  font-family: var(--mono);
  font-size: 0.9rem;
  color: var(--ink);
  white-space: nowrap;
}
.ledger tbody th a { color: var(--terracotta-deep); }
.ledger tbody th a:hover { text-decoration: underline; }
.ledger tbody td:last-child,
.ledger thead th:last-child { padding-right: 0; }
.ledger-note {
  margin-top: 1.4rem;
  font-size: 0.88rem;
  color: var(--ink-soft);
  max-width: 46rem;
}
.ledger-note a { color: var(--terracotta-deep); text-decoration: underline; }
.ledger-note a:hover { text-decoration-thickness: 2px; }

/* A value we could not verify is shown in italics and reads as provisional,
   not as a fact. The page invites the reader to check these numbers, so a
   number we cannot vouch for must not look like one we can. */
.ledger-unverified { font-style: italic; color: var(--ink-soft); }
.ledger-note-stale { color: var(--ink-soft); font-style: italic; }

/* The dark band variant: the ruled lines and the secondary text have to
   flip, or the table reads as a black slab. */
.band-ink-soft .ledger thead th,
.band-dark .ledger thead th { color: rgba(244, 239, 230, 0.62); }
.band-ink-soft .ledger thead th,
.band-ink-soft .ledger tbody th,
.band-ink-soft .ledger tbody td { border-bottom-color: var(--line-dark); }
.band-ink-soft .ledger tbody th { color: var(--paper); }
.band-ink-soft .ledger tbody td { color: rgba(244, 239, 230, 0.78); }
.band-ink-soft .ledger tbody th a { color: var(--ochre); }
.band-ink-soft .ledger-note { color: rgba(244, 239, 230, 0.7); }
.band-ink-soft .ledger-note a { color: var(--ochre); }

/* Below 900px the five-column repository table has no room: the language
   and last-push columns are dropped and the description wraps under the
   repository name. */
@media (max-width: 900px) {
  .ledger .col-lang,
  .ledger .col-push { display: none; }
  .ledger tbody th,
  .ledger tbody td { padding-right: 0.9rem; }
}

/* Below 700px even two columns are too tight, so each row becomes a
   stacked block: the repository name on its own line, then the description
   beneath it. The row header keeps its label via data-label, so the
   relationship survives the change of shape. */
@media (max-width: 700px) {
  .ledger thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .ledger tbody tr { display: block; padding: 1.2rem 0; }
  .ledger tbody th,
  .ledger tbody td { display: block; border-bottom: 0; padding: 0 0 0.45rem; }
  .ledger tbody th { white-space: normal; padding-bottom: 0.3rem; }
  .ledger tbody td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-family: var(--mono);
    font-size: 0.62rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: 0.25rem;
  }
  .ledger tbody th[data-label]::before {
    content: attr(data-label);
    display: block;
    font-family: var(--mono);
    font-size: 0.62rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: 0.3rem;
  }
  .ledger tbody td:last-child { padding-bottom: 0; }
  .ledger tbody tr + tr { border-top: 1px solid var(--line); }
  .band-ink-soft .ledger tbody tr + tr { border-top-color: var(--line-dark); }
  .band-ink-soft .ledger tbody td[data-label]::before,
  .band-ink-soft .ledger tbody th[data-label]::before { color: rgba(244, 239, 230, 0.62); }
}

/* ----------------------------------------------------------------- address */

/* The address section pairs the map with the postal address. The map is a
   static composite, so there is no third-party iframe and nothing loads
   from a visitor's browser - the same privacy posture the rest of the
   site takes. */
.split-address { align-items: start; }
.split-address .split-media img {
  aspect-ratio: 4 / 3;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-soft);
}
.map-attribution {
  margin-top: 0.6rem;
  font-size: 0.72rem;
  color: var(--ink-soft);
}
.map-attribution a { color: var(--ink-soft); text-decoration: underline; }
.map-attribution a:hover { color: var(--terracotta-deep); }

.address-block {
  display: block;
  font-style: normal;
  padding-bottom: 1.4rem;
  border-bottom: 1px solid var(--line);
}
.address-block .card-tag { display: block; margin-bottom: 0.7rem; }
.address-lines {
  font-size: 1.05rem;
  line-height: 1.65;
  color: var(--ink);
}
.address-lines strong { font-weight: 600; letter-spacing: 0.01em; }

.address-details { margin: 1.4rem 0 0; display: grid; gap: 0.9rem; }
.address-details > div {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: 0.8rem;
  align-items: baseline;
}
.address-details dt {
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.address-details dd { margin: 0; font-size: 0.98rem; }
.address-details a { color: var(--terracotta-deep); }
.address-details a:hover { text-decoration: underline; }
.split-address .hero-actions { margin-top: 1.8rem; }

@media (max-width: 700px) {
  .address-details > div { grid-template-columns: 1fr; gap: 0.2rem; }
}

/* The postal address sits under the footer's contact links, so it is set
   as a small block rather than a link - it is not a navigation target. */
.footer-address {
  font-style: normal;
  font-size: 0.9rem;
  line-height: 1.5;
  color: rgba(244, 239, 230, 0.55);
  margin-top: 0.2rem;
}
