/*
 * Cyber Media Design.
 *
 * The studio sells websites to Irish small businesses, so the most
 * characteristic object in its world is a website in a browser. That is the
 * design system: one restrained browser frame, used large in the hero and
 * again as the shape of every example card. Everything else stays quiet so
 * the work is what carries the page.
 *
 * Palette (measured, all text pairings AA or better):
 *   charcoal on cream  13.27:1      cream on forest   10.91:1
 *   forest   on cream  10.91:1      sage  on forest    9.72:1
 *   charcoal on sage   11.83:1      forest on sage     9.72:1
 *   muted    on cream   5.63:1      muted on sage      5.02:1
 *   faint    on cream   7.70:1      faint on sage      6.86:1
 * --faint was #646B62 (5.11:1 / 4.55:1). It passed AA and read weak: it is
 * used almost entirely at 13px, where a bare pass is not enough. #4A5049 is
 * the same hue, measured at 7.70:1 on cream and 6.86:1 on sage — AAA for
 * body text, comfortably clear at 13px, and still visibly quieter than
 * --muted so the hierarchy it exists to carry survives.
 * --rule (#CDD3C8) is the only value outside that set. It is a hairline and
 * carries no text and no control boundary — form inputs and the preview
 * buttons take --muted / --faint borders instead, both well over the 3:1
 * that a real UI boundary needs.
 *
 * Light only, by decision. A dark variant is a different design, not a
 * setting, and a test asserts no colour-scheme media query appears here.
 */

:root {
  --cream: #f7f7f0;
  --forest: #183f2e;
  --charcoal: #172f26;
  --sage: #e6ecdc;
  --muted: #5f645c;
  --faint: #4a5049;
  --rule: #cdd3c8;

  --sans: 'Manrope', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  --shell: 1200px;
  --gutter: clamp(20px, 5vw, 48px);
  --radius: 12px;
  /*
   * Space BETWEEN sections. Was clamp(72px, 9vw, 124px), which put a quarter
   * of a laptop screen of empty cream between a heading and the section
   * above it and made the lower half of the page feel padded out rather than
   * generous. Mobile is tuned separately below, not left to the clamp floor.
   */
  --band: clamp(56px, 6.4vw, 92px);
  /* The two sections that were worst for it: how-it-works and the FAQs are
     four short cards and a list of one-line summaries, and neither needs a
     full band above and below its own content. */
  --band-tight: clamp(44px, 5vw, 68px);
}

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

body {
  margin: 0;
  background: var(--cream);
  color: var(--charcoal);
  font: 400 17px/1.62 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
}

ul,
ol {
  padding: 0;
  margin: 0;
  list-style: none;
}

h1,
h2,
h3,
p,
figure {
  margin: 0;
}

/* Type scale. One family does the work; the serif appears once on the page. */
h1,
h2 {
  font-family: var(--sans);
  font-weight: 800;
  letter-spacing: -0.032em;
  line-height: 1.04;
}
h2 {
  font-size: clamp(30px, 3.2vw, 42px);
  letter-spacing: -0.028em;
  line-height: 1.08;
}
h3 {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.016em;
  line-height: 1.25;
}

.lede {
  color: var(--muted);
  font-size: 18px;
  max-width: 62ch;
}

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

/*
 * Space BETWEEN sections is generous; space INSIDE a heading block is tight,
 * so a heading, its lede and the thing they introduce read as one object
 * rather than three stranded ones.
 */
.section {
  padding-block: var(--band);
}
/* Declared after .section, and with the same specificity, so source order
   is what decides — the trap this file is most exposed to, since every
   section carries both classes. */
.section-tight {
  padding-block: var(--band-tight);
}
.section-sage {
  background: var(--sage);
}
/*
 * The enquiry. Its foot is the one place a band of padding buys nothing:
 * the footer below it is the same forest green with no seam between them,
 * so the section's bottom padding and the footer's top padding stacked into
 * roughly 200px of empty green under the send button. The top keeps a full
 * band — that gap is a real one, between the FAQs and the enquiry.
 */
.section-forest {
  background: var(--forest);
  color: var(--cream);
  padding-block: var(--band) clamp(36px, 3.6vw, 52px);
}
.section-head {
  margin-bottom: clamp(28px, 3.4vw, 44px);
  max-width: 62ch;
}
.section-head .lede {
  margin-top: 12px;
}

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

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--gutter);
  z-index: 100;
  background: var(--forest);
  color: var(--cream);
  padding: 10px 18px;
  border-radius: 6px;
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
}
.skip-link:focus {
  top: 12px;
}

:focus-visible {
  outline: 2px solid var(--forest);
  outline-offset: 3px;
  border-radius: 2px;
}
/* Forest ground: a forest outline would be invisible against it. */
.section-forest :focus-visible,
.site-footer :focus-visible {
  outline-color: var(--cream);
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 8px;
  min-height: 48px;
  padding: 13px 26px;
  border-radius: 8px;
  font: 700 15px/1.2 var(--sans);
  letter-spacing: -0.01em;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.btn-primary {
  background: var(--forest);
  color: var(--cream);
}
.btn-primary,
.btn-primary:visited {
  color: var(--cream);
}
.btn-primary:hover,
.btn-primary:focus-visible {
  background: #0f2c1f;
  color: var(--cream);
}
.hero-title span {
  display: block;
}
.btn-ghost {
  background: transparent;
  color: var(--charcoal);
  border-color: var(--muted);
}
.btn-ghost:hover {
  background: var(--sage);
  border-color: var(--forest);
}
/*
 * 44px, not 40. Small does not mean hard to hit: WCAG 2.5.5 and every mobile
 * HIG put the floor at 44, and these are the header CTA and the example
 * selectors -- the controls a phone visitor reaches for first.
 */
.btn-sm {
  min-height: 44px;
  padding: 11px 18px;
  font-size: 14px;
}
.btn-block {
  display: flex;
  width: 100%;
}

.text-link {
  color: var(--forest);
  font-weight: 700;
  font-size: 15px;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
}

/* ---------------------------------------------------------------- masthead */
.masthead {
  border-bottom: 1px solid var(--rule);
  background: var(--cream);
}
.masthead-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-block: 16px;
}

/*
 * The wordmark, set rather than typed: two tightly-tracked lines with the
 * second in forest. It is the smallest piece of evidence on the page that
 * the people selling type-setting can set type.
 */
.brand {
  display: inline-flex;
  flex-direction: column;
  font-weight: 800;
  /* 17px sat level with the nav links and read as one more item in the row.
     21px gives the identity a rank of its own without crowding: the nav is
     four 15px links and a small button, and the pair is measured at 820px
     and 1024px, where the row is tightest. Stepped down in the tablet
     media query below rather than left to overlap. */
  font-size: 21px;
  line-height: 0.96;
  letter-spacing: -0.042em;
  color: var(--charcoal);
  text-decoration: none;
}
.brand-mark {
  color: var(--forest);
}

/* Sized to a comfortable target, not to its own glyph: at 11px of padding
   around a 2px bar the whole control was 26px tall, which is a miss on a
   phone and this is the only way to the nav there. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  background: transparent;
  border: 1px solid var(--muted);
  border-radius: 8px;
  padding: 0;
  cursor: pointer;
}
.nav-toggle::before {
  content: '';
  display: block;
  width: 18px;
  height: 2px;
  background: var(--charcoal);
  box-shadow: 0 6px 0 var(--charcoal), 0 -6px 0 var(--charcoal);
}
.nav {
  display: flex;
  align-items: center;
  gap: 30px;
}
.nav ul {
  display: flex;
  gap: 26px;
}
/*
 * Scoped away from .btn on purpose. `.nav a` (0-1-1) outranks `.btn-primary`
 * (0-1-0), so the header CTA rendered in muted grey on forest green at a
 * ratio of 1.94 to 1, far under the 4.5 floor. Buttons keep their own
 * colour wherever they sit.
 */
.nav a:not(.btn) {
  text-decoration: none;
  font-size: 15px;
  font-weight: 500;
  color: var(--muted);
  transition: color 0.18s ease;
}
.nav a:not(.btn):hover {
  color: var(--charcoal);
}

/* -------------------------------------------------------------------- hero */
.hero {
  padding-block: clamp(52px, 7vw, 92px) clamp(48px, 6vw, 84px);
}
.hero-inner {
  display: grid;
  grid-template-columns: minmax(0, 29rem) minmax(0, 1fr);
  gap: clamp(36px, 5vw, 72px);
  align-items: center;
}
.hero-solo .hero-inner {
  grid-template-columns: minmax(0, 34rem);
}

.hero-title {
  font-size: clamp(38px, 5.4vw, 66px);
  margin-bottom: 22px;
}
.hero-lede {
  color: var(--muted);
  font-size: 19px;
  line-height: 1.58;
  max-width: 44ch;
  margin-bottom: 30px;
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 20px;
}
.hero-price {
  color: var(--faint);
  font-size: 14px;
  font-weight: 500;
}

/* ------------------------------------------------------------ browser frame */
/*
 * One frame, two sizes. Restrained on purpose: a chrome bar, an address
 * pill, a hairline. No traffic lights, no glass, no glow — the screenshot
 * inside it is the thing worth looking at.
 */
.frame {
  background: var(--sage);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}
.frame-bar {
  display: flex;
  align-items: center;
  min-width: 0;
  padding: 9px 12px;
  border-bottom: 1px solid var(--rule);
}
.frame-url {
  display: block;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  background: var(--cream);
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 3px 12px;
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
}
.frame-shot {
  width: 100%;
  height: auto;
}

/* The one shadow on the site, on the one element meant to sit forward. */
.hero-preview .frame {
  box-shadow: 0 26px 50px -34px rgba(23, 47, 38, 0.5);
}
/* The captures are 1920x1260 of a much longer page, so the frame has to cut
   somewhere. Cropping to a 19/10 viewport lands the cut at the foot of each
   sample's own hero rather than halfway through its next heading, which read
   as a rendering fault rather than as a scroll position. */
.hero-preview .frame-shot {
  aspect-ratio: 19 / 10;
  object-fit: cover;
  object-position: top center;
}

.preview-stack {
  display: grid;
  gap: 20px;
}
.preview-caption {
  margin-top: 10px;
  color: var(--faint);
  font-size: 13px;
  font-weight: 500;
}
/*
 * With JavaScript off, all three panes stay stacked and visible and the
 * control row is never shown — the same gating the mobile nav uses. Nothing
 * is hidden behind a button that cannot work.
 */
.preview-controls {
  display: none;
}
html.js .preview-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
}
html.js .preview-pane {
  display: none;
}
html.js .preview-pane.is-active {
  display: block;
}

.preview-btn {
  min-height: 44px;
  padding: 10px 15px;
  border-radius: 999px;
  border: 1px solid var(--faint);
  background: var(--cream);
  color: var(--charcoal);
  font: 600 14px/1.2 var(--sans);
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.preview-btn:hover {
  background: var(--sage);
}
.preview-btn.is-active {
  background: var(--forest);
  border-color: var(--forest);
  color: var(--cream);
}

/* ---------------------------------------------------------- benefits band */
.benefits {
  border-top: 1px solid var(--rule);
}
.benefits-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 3.5vw, 48px);
  padding-block: clamp(36px, 4.5vw, 56px);
}
.benefit-title {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.016em;
  line-height: 1.3;
  padding-top: 14px;
  border-top: 2px solid var(--forest);
}
.benefit-copy {
  margin-top: 8px;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.55;
}

/* ---------------------------------------------------------------- examples */
.example-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.4vw, 28px);
}
.example-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--cream);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 0.18s ease, transform 0.18s ease;
}
.example-card:hover {
  border-color: var(--forest);
}
.example-card:focus-within {
  outline: 2px solid var(--forest);
  outline-offset: 3px;
}
.frame-card {
  border: 0;
  border-radius: 0;
  border-bottom: 1px solid var(--rule);
}
.frame-card .frame-shot {
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: top center;
}
.example-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 22px 22px 24px;
}
.example-trade {
  color: var(--faint);
  font-size: 13px;
  font-weight: 600;
}
.example-name {
  font-size: 21px;
}
/* One link per card, stretched over the card so the whole surface is a
   target while the accessibility tree still carries a single named link. */
.example-link {
  text-decoration: none;
  color: inherit;
}
.example-link::after {
  content: '';
  position: absolute;
  inset: 0;
}
.example-link:focus-visible {
  outline: none;
}
.example-blurb {
  color: var(--muted);
  font-size: 15px;
  line-height: 1.55;
}
.example-flag {
  margin-top: 2px;
  color: var(--faint);
  font-size: 13px;
  font-weight: 600;
}
/* Pushed to the foot of the card so three cards with blurbs of different
   lengths still line their links up with each other. */
.example-body .text-link {
  margin-top: auto;
}

/* ------------------------------------------- one design, desktop and phone */
/*
 * The claim every web seller makes and no small business can check is "it
 * works on mobile". So it is shown: the same built page, captured once at
 * 1920x1260 and once at a real 1170x2532 phone viewport, side by side.
 *
 * It sits at the foot of the examples section rather than in the hero. The
 * hero already carries a full-width browser frame and a switcher; a second
 * pair of screenshots above the fold would have been two proofs competing
 * for the same glance. Here it lands after a reader has seen three designs
 * and is asking what one of them is actually like to use.
 *
 * Framing borrows the browser frame's whole vocabulary — hairline, rounded
 * corner, one small pill — at a phone's proportions. No device photograph,
 * no glass, no glow.
 */
.devices {
  margin-top: clamp(40px, 4.6vw, 60px);
  padding-top: clamp(32px, 4vw, 52px);
  border-top: 1px solid var(--rule);
}
.devices-head {
  max-width: 58ch;
  margin-bottom: clamp(24px, 3vw, 36px);
}
.devices-title {
  font-size: clamp(21px, 2.2vw, 26px);
}
.devices-copy {
  margin-top: 10px;
  color: var(--muted);
  font-size: 16px;
  line-height: 1.55;
}
/* Bottom-aligned, not centred: the two devices are standing on the same
   surface, and a phone floating half a frame up reads as a collage. */
.devices-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(150px, 18vw, 232px);
  gap: clamp(18px, 3vw, 40px);
  align-items: end;
}
.devices .frame,
.phone {
  box-shadow: 0 26px 50px -34px rgba(23, 47, 38, 0.5);
}
.phone {
  padding: 13px 8px 8px;
  background: var(--cream);
  border: 1px solid var(--rule);
  border-radius: 30px;
}
.phone-slot {
  display: block;
  width: 40px;
  height: 4px;
  margin: 0 auto 8px;
  border-radius: 999px;
  background: var(--rule);
}
.phone-shot {
  width: 100%;
  height: auto;
  border-radius: 22px;
}
.devices-flag {
  margin-top: 14px;
  color: var(--faint);
  font-size: 13px;
  font-weight: 600;
}

/* ----------------------------------------------------------------- pricing */
.price-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(20px, 2.4vw, 28px);
}
.price-card {
  display: flex;
  flex-direction: column;
  background: var(--cream);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: clamp(24px, 2.6vw, 34px);
}
/* Emphasis without a claim: the Business package is tinted and outlined
   because it is the larger of the two, not because anyone said it sells
   best. Both cards carry a "who it suits" label, so neither reads as a
   ranking. */
.price-card.is-featured {
  background: var(--sage);
  border-color: var(--forest);
}
.price-suits {
  color: var(--faint);
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 10px;
}
.price-name {
  font-size: 22px;
}
.price-value {
  font-size: clamp(30px, 3vw, 38px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin: 6px 0 12px;
}
.price-summary {
  color: var(--muted);
  font-size: 16px;
  line-height: 1.55;
  max-width: 42ch;
}
/* Same reason as the example cards: two packages with different numbers of
   deliverables still put their buttons on the same line. The clearance
   above the button comes from the list's own margin, not from padding on
   the button — padding here would push its label off centre. */
.price-card .ticks {
  margin-bottom: 26px;
}
.price-cta {
  margin-top: auto;
}

.ticks {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin-top: 20px;
}
.ticks li {
  position: relative;
  padding-left: 24px;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.5;
}
.ticks li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 8px;
  width: 10px;
  height: 6px;
  border-left: 2px solid var(--forest);
  border-bottom: 2px solid var(--forest);
  transform: rotate(-45deg);
}

/* Ongoing care: underneath, and shaped differently, because it is an
   optional subscription and not a third way to start. */
.ongoing {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(24px, 3vw, 48px);
  align-items: start;
  margin-top: clamp(20px, 2.4vw, 28px);
  padding: clamp(24px, 2.6vw, 34px);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}
.ongoing-label {
  color: var(--faint);
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 10px;
}
.ongoing-name {
  font-size: 22px;
}
.ongoing-value {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.028em;
  margin: 4px 0 10px;
}
.ongoing-summary {
  color: var(--muted);
  font-size: 16px;
  line-height: 1.55;
  max-width: 46ch;
  margin-bottom: 18px;
}
.ongoing .ticks {
  margin-top: 0;
}
/* Hosting and the domain are billed separately, at cost. It is in the
   footnote under all three prices too, but this is the price it is most
   often read into, so it is stated on the card as well. */
.ongoing-note {
  margin-top: 16px;
  color: var(--faint);
  font-size: 14px;
  line-height: 1.5;
  max-width: 46ch;
}

.fine {
  margin-top: 24px;
  color: var(--faint);
  font-size: 13px;
  max-width: 70ch;
}

/* ----------------------------------------------------------------- process */
.process-list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(20px, 2.6vw, 34px);
  counter-reset: step;
}
.process-step {
  border-top: 2px solid var(--forest);
  padding-top: 16px;
}
.process-number {
  display: block;
  font-size: 13px;
  font-weight: 700;
  color: var(--forest);
  margin-bottom: 10px;
}
.process-title {
  font-size: 19px;
}
.process-copy {
  margin-top: 8px;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.55;
}

/* --------------------------------------------------------------------- faq */
/*
 * The heading sits above the list, not beside it. This band used to be a
 * two-column grid — a 19rem column holding four words and a one-line lede,
 * next to six accordion rows — so the taller the list got, the more of the
 * page's left-hand side was empty, and the FAQs read as a hole rather than a
 * section. Every other section on the page introduces itself from above with
 * the same `.section-head`; this one now does too, which is one idiom
 * instead of two.
 *
 * The list then takes the full shell in two columns, like every other band
 * on the page (benefits three, examples three, process four). Six questions
 * in one 1100px column would have moved the empty area from the left of the
 * section to the right of it rather than removed it, and a narrow single
 * column would have left this the only band on the page not using the
 * width it is given.
 *
 * `align-items: start` is load-bearing: without it an opened answer
 * stretches its grid row and drags the neighbouring question's rule down to
 * meet it. With everything closed the rules line up across both columns
 * anyway, because those rows are the same height.
 */
.faq-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(28px, 4vw, 64px);
  align-items: start;
  border-top: 1px solid var(--rule);
}
.faq-item {
  border-bottom: 1px solid var(--rule);
}
.faq-item summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  padding-block: 18px;
  cursor: pointer;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.012em;
  list-style: none;
}
.faq-item summary::-webkit-details-marker {
  display: none;
}
.faq-item summary::after {
  content: '';
  flex: none;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--forest);
  border-bottom: 2px solid var(--forest);
  transform: translateY(-3px) rotate(45deg);
  transition: transform 0.18s ease;
}
.faq-item[open] summary::after {
  transform: translateY(2px) rotate(-135deg);
}
.faq-answer {
  padding-bottom: 20px;
}
.faq-answer p {
  color: var(--muted);
  font-size: 16px;
  max-width: 68ch;
}

/* ----------------------------------------------------------------- contact */
.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: start;
}
.contact-intro h2 {
  color: var(--cream);
}
.contact-lede {
  margin-top: 12px;
  color: var(--sage);
  font-size: 18px;
  max-width: 34ch;
}
.contact-alt {
  margin-top: 22px;
  color: var(--sage);
  font-size: 15px;
}
.contact-alt a {
  color: var(--cream);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.contact-form {
  background: var(--cream);
  color: var(--charcoal);
  border-radius: var(--radius);
  padding: clamp(24px, 2.6vw, 34px);
}
.field-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 18px;
}
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 18px;
}
.field label {
  font-size: 14px;
  font-weight: 600;
}
.req {
  color: var(--forest);
}
.field input,
.field select,
.field textarea {
  font: 400 16px/1.5 var(--sans);
  min-height: 48px;
  padding: 12px 14px;
  border: 1px solid var(--muted);
  border-radius: 8px;
  background: var(--sage);
  color: var(--charcoal);
  resize: vertical;
}
.field input::placeholder,
.field textarea::placeholder {
  color: var(--faint);
}
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: 2px solid var(--forest);
  outline-offset: 1px;
}
/*
 * The package select. The native arrow is replaced with the same chevron the
 * FAQ rows use — one marker shape on the page, not two — drawn on a wrapper
 * so it can sit over the control without becoming a click target of its own.
 */
.select-wrap {
  position: relative;
  display: block;
}
.field select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  padding-right: 42px;
  cursor: pointer;
}
.select-wrap::after {
  content: '';
  position: absolute;
  right: 17px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -7px;
  border-right: 2px solid var(--forest);
  border-bottom: 2px solid var(--forest);
  transform: rotate(45deg);
  pointer-events: none;
}
.field-hint {
  color: var(--faint);
  font-size: 13px;
}
.form-status {
  margin-top: 14px;
  min-height: 1.2em;
  color: var(--muted);
  font-size: 14px;
}

/*
 * Turnstile. The widget draws itself into a fixed 300x65 iframe inside the
 * cream form card; the height is reserved only under `html.js`, because
 * with JavaScript off nothing ever fills it and an empty 65px band would
 * push the <noscript> message away from the button it is explaining.
 * `data-theme="light"` is set on the element itself — this site is light
 * only, and the widget would otherwise follow the visitor's system theme
 * onto a cream card.
 */
.cf-turnstile {
  margin-bottom: 18px;
}
html.js .cf-turnstile {
  min-height: 65px;
}
.form-noscript {
  margin-bottom: 18px;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.55;
}
.form-noscript a {
  color: var(--forest);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/*
 * Honeypot: hidden in CSS, not with type="hidden" — a bot that skips
 * literally-hidden inputs will still find and fill one that only looks
 * hidden through layout, which is what catches it.
 */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ------------------------------------------------------------ legal pages */
/*
 * Long-form text, unlike anything else on this site: the global reset sets
 * h1/h2/p margins to 0 and strips list bullets, which is right for the
 * card-driven homepage but leaves a wall of unbroken text here. Scoped to
 * .legal-* classes that only ever appear on /privacy/ and /terms/.
 */
.legal h1 {
  font-size: clamp(32px, 4vw, 46px);
  margin-bottom: 12px;
}
.legal-shell {
  max-width: 70ch;
}
.legal-updated {
  color: var(--faint);
  font-size: 14px;
  margin: 0 0 40px;
}
.legal-section {
  margin-top: 40px;
  padding-top: 32px;
  border-top: 1px solid var(--rule);
}
.legal-section:first-of-type {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}
.legal-section h2 {
  font-size: clamp(21px, 2.6vw, 26px);
  margin: 0 0 16px;
}
.legal-section p {
  color: var(--muted);
  margin: 0 0 16px;
}
.legal-section p:last-child {
  margin-bottom: 0;
}
.legal-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0 0 16px;
}
.legal-list li {
  position: relative;
  padding-left: 22px;
  color: var(--muted);
}
.legal-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 10px;
  width: 8px;
  height: 2px;
  background: var(--forest);
}
.legal-list:last-child {
  margin-bottom: 0;
}

/* 404 */
#not-found h1 {
  font-size: clamp(34px, 4.4vw, 52px);
  margin-bottom: 14px;
}
#not-found .lede {
  margin-bottom: 28px;
}

/* ------------------------------------------------------------------ footer */
/*
 * Forest, continuing the enquiry band above it without a seam, so the page
 * closes on one solid field instead of trailing off into another tint.
 */
.site-footer {
  background: var(--forest);
  color: var(--sage);
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr;
  gap: 32px;
  padding-block: clamp(36px, 4vw, 56px);
}
.site-footer .brand {
  font-size: 22px;
  color: var(--cream);
}
.site-footer .brand-mark {
  color: var(--sage);
}
.footer-copy {
  color: var(--sage);
  font-size: 15px;
  margin: 16px 0 12px;
  max-width: 38ch;
}
.footer-ident {
  color: var(--sage);
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 14px;
}
.footer-contact {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.footer-contact a {
  color: var(--cream);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.footer-col-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--cream);
  margin: 0 0 14px;
}
.footer-col ul {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.footer-col a {
  text-decoration: none;
  color: var(--sage);
  font-size: 15px;
  transition: color 0.18s ease;
}
.footer-col a:hover {
  color: var(--cream);
  text-decoration: underline;
  text-underline-offset: 4px;
}
.footer-legal {
  border-top: 1px solid rgba(230, 236, 220, 0.22);
  padding-block: 20px;
  color: var(--sage);
  font-size: 13px;
}

/* -------------------------------------------------------------- responsive */
/*
 * Tablet: the masthead row is at its tightest here — the nav is still
 * horizontal, still four links and a button, and the gutter has shrunk. Step
 * the wordmark back down rather than let it push the nav into a wrap.
 */
@media (max-width: 1024px) {
  .brand {
    font-size: 19px;
  }
  .nav {
    gap: 22px;
  }
  .nav ul {
    gap: 20px;
  }
}

@media (max-width: 1000px) {
  .hero-inner {
    /* Text above the preview on the way down to mobile: the pitch has to be
       read before the proof is worth looking at. */
    grid-template-columns: minmax(0, 1fr);
    gap: 36px;
  }
  .hero-lede {
    max-width: 52ch;
  }
  .example-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .process-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .contact-grid,
  .ongoing,
  .faq-list {
    grid-template-columns: minmax(0, 1fr);
  }
  .contact-lede {
    max-width: 56ch;
  }
}

@media (max-width: 760px) {
  .benefits-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
  }
  .example-grid,
  .price-grid,
  .process-list {
    grid-template-columns: minmax(0, 1fr);
  }
  .field-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
  .footer-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  .footer-brand {
    grid-column: 1 / -1;
  }
  /* Side by side stops working once the desktop capture is narrower than a
     phone is tall. Stack them, centred, and let the phone keep a size worth
     reading rather than shrink both to fit a row. */
  .devices-pair {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    gap: 24px;
  }
  .devices .frame-desktop {
    width: 100%;
  }
  .phone {
    width: min(248px, 74vw);
  }
  .devices-figure {
    text-align: center;
  }
}

@media (max-width: 620px) {
  .hero-actions .btn {
    width: 100%;
  }
  .footer-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  /*
   * The toggle stays hidden, and the nav stays a plain visible stacked
   * list, until main.js marks <html class="js"> — so with JavaScript
   * switched off the nav is never behind a dead button.
   */
  .nav {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding-top: 16px;
  }
  html.js .nav-toggle {
    display: inline-flex;
  }
  html.js .nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 20;
    background: var(--cream);
    border-bottom: 1px solid var(--rule);
    padding: 20px var(--gutter) 28px;
    display: none;
  }
  html.js .nav.is-open {
    display: flex;
  }
  .nav ul {
    flex-direction: column;
    gap: 14px;
    width: 100%;
  }
  .masthead-inner {
    position: relative;
  }
}

/* ---------------------------------------------------------------- motion */
/*
 * Nothing on this page animates on its own; the only transitions are hover
 * and the FAQ marker, both answers to something a person did. Honour the
 * setting anyway — a person who asks for no motion should get none.
 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Ties every price to the VAT footnote. Decorative for assistive tech --
   the footnote itself is read out in the same section. */
.price-mark {
  font-size: 0.5em;
  vertical-align: super;
  line-height: 0;
  margin-left: 2px;
  color: var(--muted);
}
