@layer reset, tokens, base, layout, sections, components, motion;

/* ------------------------------------------------------------------ */
/* Fonts                                                              */
/* ------------------------------------------------------------------ */

@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/newsreader-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/newsreader-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ------------------------------------------------------------------ */
/* Reset                                                              */
/* ------------------------------------------------------------------ */

@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  * { margin: 0; }
  html { -webkit-text-size-adjust: none; text-size-adjust: none; }
  body { min-height: 100svh; }
  img, picture, svg { display: block; max-width: 100%; height: auto; }
  input, button, textarea, select { font: inherit; color: inherit; }
  p, h1, h2, h3 { overflow-wrap: break-word; }
  ul[role="list"], ol[role="list"] { list-style: none; padding: 0; }
}

/* ------------------------------------------------------------------ */
/* Tokens                                                             */
/* ------------------------------------------------------------------ */

@layer tokens {
  :root {
    color-scheme: light;

    /* Sand and moss */
    --bg: #ddd6c6;
    --surface: #d2cab8;
    --ink: #2a2a26;
    --muted: #4f4d45;
    --line: rgb(42 42 38 / 0.18);
    --guide: rgb(42 42 38 / 0.07);
    --accent: #4f6238;
    --accent-hover: #3f5a2a;
    --accent-ink: #ffffff;
    --paper: #f2f2ee;
    --field: #3f5a2a;
    --field-ink: #ffffff;
    --field-muted: #d3dcc8;
    --field-soft: #e4e9dd;
    --field-line: rgb(255 255 255 / 0.3);
    --footer-muted: #bdbab0;
    --footer-mark: #36362f;
    --error: #8a2a1d;

    /* Type: one family, six sizes */
    --font: "Newsreader", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
    --step--1: 0.9375rem;                                   /* labels, meta, fine print */
    --step-0: clamp(1.0625rem, 1rem + 0.2vw, 1.1875rem);    /* body, nav, buttons */
    --step-1: clamp(1.25rem, 1.15rem + 0.45vw, 1.5rem);     /* leads, card titles */
    --step-2: clamp(1.5rem, 1.3rem + 0.9vw, 2rem);          /* project titles */
    --step-3: clamp(2.25rem, 1.6rem + 2.6vw, 3.5rem);       /* section headings */
    --step-4: clamp(3.25rem, 1.6rem + 6.4vw, 7.5rem);       /* page title */
    --step-5: clamp(4rem, 20.5vw, 17.75rem);                /* footer wordmark, sized to the container */

    /* Space: one scale used everywhere */
    --space-1: 0.5rem;
    --space-2: 1rem;
    --space-3: 1.5rem;
    --space-4: 2.5rem;
    --space-5: 4rem;
    --section-space: clamp(4.5rem, 8vw, 7.5rem);

    /* Layout */
    --container: 76rem;
    --gutter: clamp(1.25rem, 4vw, 3rem);
    --gap: clamp(1.5rem, 3vw, 3rem);
    --header-height: 4.5rem;

    --radius: 0;
    --control-height: 3rem;

    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --duration: 600ms;
  }
}

/* ------------------------------------------------------------------ */
/* Base                                                               */
/* ------------------------------------------------------------------ */

@layer base {
  html {
    scroll-behavior: smooth;
    scroll-padding-top: var(--header-height);
  }

  body {
    background: var(--bg);
    color: var(--ink);
    font-family: var(--font);
    font-size: var(--step-0);
    font-optical-sizing: auto;
    line-height: 1.6;
    font-kerning: normal;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
  }

  h1, h2, h3 {
    font-weight: 400;
    line-height: 1.1;
    letter-spacing: -0.02em;
    text-wrap: balance;
  }

  h2 {
    font-size: var(--step-3);
    font-weight: 300;
    line-height: 1.05;
    letter-spacing: -0.03em;
  }

  h3 {
    font-size: var(--step-1);
    line-height: 1.25;
    letter-spacing: -0.01em;
  }

  p, li, dd, summary { text-wrap: pretty; }

  a, button, summary {
    touch-action: manipulation;
    -webkit-tap-highlight-color: rgb(42 42 38 / 0.12);
  }

  a {
    color: inherit;
    text-decoration-line: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    transition: text-decoration-color 200ms ease, color 200ms ease;
  }

  a:hover { text-decoration-thickness: 2px; }

  :focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 4px;
  }

  ::selection {
    background: var(--accent);
    color: var(--accent-ink);
  }

  /* Moss on the moss band would disappear, so selection inverts there */
  .section--field ::selection {
    background: var(--paper);
    color: var(--field);
  }

  strong { font-weight: 600; }

  .visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px; /* taste-skill-ignore: visually hidden text, not a rule */
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }

  .skip-link {
    position: absolute;
    top: var(--space-2);
    left: var(--space-2);
    z-index: 100;
    padding: 0.75rem var(--space-2);
    background: var(--ink);
    color: var(--paper);
    font-size: var(--step--1);
    transform: translateY(-200%);
  }

  .skip-link:focus { transform: none; }
}

/* ------------------------------------------------------------------ */
/* Layout                                                             */
/* ------------------------------------------------------------------ */

@layer layout {
  .container {
    width: 100%;
    max-width: calc(var(--container) + 2 * var(--gutter));
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  /*
   * Every two-part section splits on the same centre line, so the second
   * column starts at the same x on every section of the page.
   */
  .split {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--gap);
    row-gap: var(--space-4);
    align-items: start;
  }

  .stack {
    display: grid;
    align-content: start;
    gap: var(--space-3);
  }

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

  .section--surface { background: var(--surface); }

  .section--field {
    background: var(--field);
    color: var(--field-ink);
  }

  .section-head {
    align-items: end;
    row-gap: var(--space-3);
    margin-bottom: var(--space-5);
  }

  .section-head p { max-width: 42ch; }

  .lead {
    font-size: var(--step-1);
    line-height: 1.45;
  }

  .muted { color: var(--muted); }

  .section--field .section-head p { color: var(--field-soft); }
}

/* ------------------------------------------------------------------ */
/* Sections                                                           */
/* ------------------------------------------------------------------ */

@layer sections {

  /* Header --------------------------------------------------------- */

  /* The rule under the header only appears once the page has scrolled */
  .site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--bg);
    border-bottom: 1px solid transparent;
    transition: border-color 200ms ease;
  }

  .site-header.is-scrolled { border-bottom-color: var(--line); }

  .site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    min-height: var(--header-height);
  }

  .wordmark {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    text-decoration: none;
    white-space: nowrap;
  }

  .site-nav {
    display: flex;
    align-items: center;
    gap: var(--space-4);
  }

  .site-nav ul {
    display: flex;
    gap: var(--space-4);
    font-size: var(--step--1);
  }

  .menu-toggle {
    min-height: 2.75rem;
    padding: 0 var(--space-2);
    border: 1px solid var(--ink);
    border-radius: var(--radius);
    background: transparent;
    cursor: pointer;
  }

  .menu-toggle[aria-expanded="true"] {
    background: var(--ink);
    color: var(--paper);
  }

  /* Hero ----------------------------------------------------------- */

  .hero {
    position: relative;
    display: grid;
    align-items: center;
    padding-block: var(--space-5);
  }

  /* Faint guides for the four columns the hero is laid out on */
  .hero__guides {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    column-gap: var(--gap);
    pointer-events: none;
  }

  .hero__guides span { border-inline: 1px solid var(--guide); }

  .hero__inner {
    position: relative;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    column-gap: var(--gap);
    row-gap: var(--space-4);
    align-items: center;
  }

  .hero__copy { grid-column: 1 / 4; }

  .hero__title {
    font-size: var(--step-4);
    font-weight: 300;
    line-height: 0.95;
    letter-spacing: -0.045em;
  }

  /* Each line is its own mask for the entrance; the padding keeps the
     descender of the g inside it */
  .hero__line {
    display: block;
    overflow: hidden;
    padding-bottom: 0.12em;
    margin-bottom: -0.12em;
  }

  .hero__line > * { display: inline-block; }

  .hero__title em {
    padding-right: 0.04em;
    color: var(--accent);
    letter-spacing: -0.03em;
  }

  .hero__lead {
    max-width: 36ch;
    margin-top: var(--space-4);
  }

  .hero__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    margin-top: var(--space-4);
  }

  /* Three plain facts, set on the last quarter and level with the actions */
  .hero__facts {
    grid-column: 4 / 5;
    align-self: end;
    display: grid;
    gap: var(--space-3);
  }

  .hero__facts div {
    display: grid;
    gap: 0.25rem;
    padding-top: var(--space-2);
    border-top: 1px solid var(--line);
  }

  .hero__facts dt {
    font-size: var(--step--1);
    color: var(--muted);
  }

  .hero__facts dd {
    margin: 0;
    font-size: var(--step-1);
    line-height: 1.3;
    letter-spacing: -0.01em;
  }

  /* Services ------------------------------------------------------- */

  /* Two independent columns, so opening an item only moves its own column */
  .services { row-gap: 0; }

  /* Pricing -------------------------------------------------------- */

  .plans {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--gap);
  }

  /* Open columns under a single rule rather than filled cards */
  .plan {
    display: grid;
    align-content: start;
    gap: var(--space-2);
    padding-top: var(--space-3);
    border-top: 1px solid var(--ink);
  }

  .plan h3 { font-weight: 500; }

  .plan__price {
    font-size: var(--step-2);
    font-weight: 300;
    line-height: 1.1;
    letter-spacing: -0.02em;
  }

  .plan__fit {
    margin-top: auto;
    padding-top: var(--space-1);
    font-size: var(--step--1);
    color: var(--muted);
  }

  .extras { margin-top: var(--space-5); }

  .detail-list { display: grid; }

  /* A price drops below its label when the card is too narrow for both */
  .detail-list div {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: 0 var(--space-2);
    padding-block: 0.625rem;
    border-bottom: 1px solid var(--line);
  }

  .detail-list div:first-child { border-top: 1px solid var(--line); }

  .detail-list dd {
    margin: 0 0 0 auto;
    text-align: right;
    font-variant-numeric: lining-nums tabular-nums;
    white-space: nowrap;
  }

  .compare {
    margin-top: var(--space-5);
    border-block: 1px solid var(--ink);
  }

  .compare[open] > summary { border-bottom: 1px solid var(--line); }

  .compare__hint {
    display: none;
    padding-top: var(--space-2);
    font-size: var(--step--1);
    color: var(--muted);
  }

  /* Positioned so visually hidden text in the cells is clipped here too,
     rather than widening the page */
  .table-scroll {
    position: relative;
    overflow-x: auto;
    overscroll-behavior-x: contain;
  }

  .compare-table {
    width: 100%;
    min-width: 44rem;
    border-collapse: collapse;
    font-size: var(--step--1);
    line-height: 1.45;
  }

  .compare-table th,
  .compare-table td {
    padding: 0.875rem var(--space-2) 0.875rem 0;
    border-bottom: 1px solid var(--line);
    text-align: left;
    vertical-align: top;
  }

  .compare-table tbody tr:last-child > * { border-bottom: 0; }

  .compare-table thead th {
    padding-block: var(--space-3) var(--space-2);
    font-size: var(--step-1);
    font-weight: 500;
    line-height: 1.25;
    vertical-align: bottom;
  }

  .compare-table thead th span {
    display: block;
    margin-top: 0.25rem;
    font-size: var(--step--1);
    font-weight: 400;
    color: var(--muted);
  }

  .compare-table tbody th {
    width: 28%;
    font-weight: 500;
  }

  /* Row labels stay put while the plan columns scroll on narrow screens */
  .compare-table tbody th,
  .compare-table thead td {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--surface);
  }

  .compare-table td { width: 24%; }

  /* Work ----------------------------------------------------------- */

  .projects { border-top: 1px solid var(--line); }

  .project {
    grid-template-rows: auto auto;
    row-gap: var(--space-1);
    align-items: baseline;
    padding-block: var(--space-4);
    border-bottom: 1px solid var(--line);
  }

  .project__title {
    grid-row: 1 / 3;
    font-size: var(--step-2);
    font-weight: 300;
    letter-spacing: -0.02em;
  }

  .project__desc,
  .project__meta { grid-column: 2; }

  .project__desc { max-width: 46ch; }

  .project__meta {
    font-size: var(--step--1);
    color: var(--muted);
  }

  /* About ---------------------------------------------------------- */

  .about__copy p { max-width: 54ch; }

  .about__panel {
    display: grid;
    gap: var(--space-2);
    padding-top: var(--space-3);
    border-top: 1px solid var(--ink);
  }

  .about__panel h3 {
    font-size: var(--step-0);
    font-weight: 600;
    letter-spacing: 0;
  }

  .about__panel h3:not(:first-child) { margin-top: var(--space-3); }

  /* Process -------------------------------------------------------- */

  .steps {
    row-gap: 0;
    counter-reset: step;
  }

  .step {
    display: grid;
    grid-template-columns: 2.75rem minmax(0, 1fr);
    column-gap: var(--space-2);
    row-gap: var(--space-1);
    align-content: start;
    padding-block: var(--space-3) var(--space-4);
    border-top: 1px solid var(--field-line);
    counter-increment: step;
  }

  .step::before {
    content: counter(step);
    grid-row: 1 / 3;
    font-size: var(--step-2);
    font-weight: 300;
    line-height: 1.1;
    color: var(--field-muted);
    font-variant-numeric: lining-nums tabular-nums;
  }

  .step h3 { padding-top: 0.125rem; }

  .step p {
    max-width: 46ch;
    color: var(--field-soft);
  }

  /* FAQ ------------------------------------------------------------ */

  /* Contact -------------------------------------------------------- */

  .contact__intro p { max-width: 36ch; }

  /* Footer --------------------------------------------------------- */

  /* The wordmark at the bottom is cropped by the footer edge */
  .site-footer {
    padding-top: var(--space-5);
    overflow: hidden;
    background: var(--ink);
    color: var(--paper);
  }

  .site-footer__brand p:not(.site-footer__name) {
    max-width: 34ch;
    color: var(--footer-muted);
  }

  .site-footer__name { font-size: var(--step-1); }

  .site-footer nav ul {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-1) var(--gap);
  }

  .site-footer__legal {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-1) var(--space-4);
    margin-top: var(--space-5);
    padding-top: var(--space-3);
    border-top: 1px solid rgb(242 242 238 / 0.2);
    font-size: var(--step--1);
    color: var(--footer-muted);
  }

  /* Decorative, so the word is drawn by CSS rather than read or contrast-checked as text */
  .site-footer__mark::before { content: "Dashwood"; }

  .site-footer__mark {
    height: 0.62em;
    margin-top: var(--space-5);
    font-size: var(--step-5);
    font-weight: 300;
    line-height: 0.8;
    letter-spacing: -0.05em;
    color: var(--footer-mark);
    white-space: nowrap;
    user-select: none;
  }

  /* Simple pages (privacy, 404) ----------------------------------- */

  .page {
    min-height: 100svh;
    display: grid;
    grid-template-rows: auto 1fr auto;
  }

  .page__body { padding-block: var(--section-space); }

  .page__title {
    font-size: var(--step-3);
    font-weight: 300;
    margin-bottom: var(--space-4);
  }

  .prose { max-width: 62ch; }

  .prose h2 {
    margin: var(--space-4) 0 var(--space-2);
    font-size: var(--step-1);
    font-weight: 500;
    line-height: 1.25;
    letter-spacing: -0.01em;
  }

  .prose p + p { margin-top: var(--space-2); }

  .prose ul {
    display: grid;
    gap: var(--space-1);
    margin-block: var(--space-2);
    padding-left: 1.25rem;
  }

  .prose ul + p { margin-top: var(--space-2); }

  .page-footer {
    padding-block: var(--space-4);
    background: var(--ink);
    color: var(--paper);
    font-size: var(--step--1);
  }

  .page-footer .container {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-2);
  }
}

/* ------------------------------------------------------------------ */
/* Components                                                         */
/* ------------------------------------------------------------------ */

@layer components {
  .button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--control-height);
    padding: 0 var(--space-3);
    border: 0;
    border-radius: var(--radius);
    background: var(--accent);
    color: var(--accent-ink);
    font-weight: 500;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 200ms ease, transform 150ms ease;
  }

  .button:hover { background: var(--accent-hover); }
  .button:active { transform: translateY(1px); }
  .button[disabled] { cursor: progress; opacity: 0.75; }

  .button--small {
    min-height: 2.75rem;
    padding: 0 1.125rem;
  }

  .text-link { font-weight: 500; }

  /* Underlines that draw from the left. Text links keep theirs at rest;
     navigation links only show one on hover or focus. */
  .text-link,
  .site-nav ul a,
  .site-footer nav a {
    position: relative;
    text-decoration: none;
  }

  .text-link::after,
  .site-nav ul a::after,
  .site-footer nav a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -0.1em;
    border-bottom: 1px solid currentColor;
    transform: scaleX(0);
    transform-origin: right;
    transition: transform 300ms var(--ease-out);
  }

  .text-link::after { transform: none; }

  .site-nav ul a:is(:hover, :focus-visible)::after,
  .site-footer nav a:is(:hover, :focus-visible)::after {
    transform: none;
    transform-origin: left;
  }

  .text-link:hover::after { animation: redraw 600ms var(--ease-out); }

  @keyframes redraw {
    0% { transform: none; transform-origin: right; }
    45% { transform: scaleX(0); transform-origin: right; }
    46% { transform: scaleX(0); transform-origin: left; }
    100% { transform: none; transform-origin: left; }
  }

  /* Disclosure ----------------------------------------------------- */

  .disclosure > summary {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-3);
    padding-block: var(--space-3);
    font-size: var(--step-1);
    line-height: 1.3;
    list-style: none;
    cursor: pointer;
  }

  .disclosure > summary::-webkit-details-marker { display: none; }

  .disclosure > summary::after {
    content: "+";
    flex: none;
    font-size: var(--step-2);
    font-weight: 300;
    line-height: 1;
    transition: transform 250ms var(--ease-out);
  }

  .disclosure[open] > summary::after { transform: rotate(45deg); }

  .disclosure > summary:hover { color: var(--accent); }

  /* A run of disclosures between single rules (services, FAQ) */
  .disclosure-list { border-top: 1px solid var(--line); }

  .disclosure-list > .disclosure { border-bottom: 1px solid var(--line); }

  .disclosure-list > .disclosure > p {
    max-width: 56ch;
    padding-bottom: var(--space-3);
    color: var(--muted);
  }

  /* Form ----------------------------------------------------------- */

  .form { display: grid; gap: var(--space-3); }

  .form__row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
  }

  .field { display: grid; gap: 0.375rem; }

  .field label {
    font-size: var(--step--1);
    font-weight: 500;
  }

  .field label .optional { font-weight: 400; color: var(--muted); }

  .field input,
  .field textarea {
    width: 100%;
    min-height: var(--control-height);
    padding: 0.625rem 0.75rem;
    border: 0;
    border-bottom: 1px solid var(--ink);
    border-radius: 0;
    background: var(--surface);
    line-height: 1.5;
    transition: background-color 200ms ease, border-color 200ms ease;
  }

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

  /* Fields on a surface band take the page colour so they still read as fields */
  .section--surface .field input,
  .section--surface .field textarea { background: var(--bg); }

  .field input:focus-visible,
  .field textarea:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 0;
    background: var(--paper);
  }

  .field [aria-invalid="true"] { border-bottom: 2px solid var(--error); }

  .field__hint,
  .field__error {
    font-size: var(--step--1);
    line-height: 1.4;
  }

  .field__hint { color: var(--muted); }
  .field__error { color: var(--error); }
  .field__error:empty { display: none; }

  /* Spam trap: kept out of sight and out of the tab order */
  .form__trap {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px; /* taste-skill-ignore: off-screen spam trap, not a rule */
    overflow: hidden;
  }

  .form__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
  }

  .form__privacy {
    max-width: 34ch;
    font-size: var(--step--1);
    color: var(--muted);
  }

  .form__status { line-height: 1.5; }

  .form__status:empty { display: none; }

  .form__status[data-state="success"] {
    padding: var(--space-2) var(--space-3);
    background: var(--field);
    color: var(--field-ink);
  }

  .form__status[data-state="error"] {
    padding: var(--space-2) var(--space-3);
    background: var(--paper);
    color: var(--error);
  }

  .turnstile:empty { display: none; }
}

/* ------------------------------------------------------------------ */
/* Motion                                                             */
/* ------------------------------------------------------------------ */

@layer motion {
  @media (prefers-reduced-motion: no-preference) {
    /* Only hidden when the script is running, so content never depends on it */
    .js [data-reveal] {
      opacity: 0;
      transform: translateY(16px);
      transition:
        opacity var(--duration) var(--ease-out),
        transform var(--duration) var(--ease-out);
      transition-delay: calc(var(--reveal-index, 0) * 70ms);
    }

    .js [data-reveal].is-visible {
      opacity: 1;
      transform: none;
    }

    /*
     * Strong rules draw across from the left once their block arrives, over
     * a faint rule that stays put. On the process band this fills each step
     * in turn as the reader works down the list.
     */
    .js :is(.plan, .about__panel, .step)[data-reveal] { position: relative; }

    .js :is(.plan, .about__panel)[data-reveal] { border-top-color: var(--line); }

    .js :is(.plan, .about__panel, .step)[data-reveal]::after {
      content: "";
      position: absolute;
      top: -1px;
      left: 0;
      right: 0;
      border-top: 1px solid var(--rule, var(--ink));
      transform: scaleX(0);
      transform-origin: left;
      transition: transform 1100ms var(--ease-out);
      transition-delay: calc(var(--reveal-index, 0) * 70ms + 200ms);
    }

    .js .step[data-reveal] { --rule: var(--field-muted); }

    .js [data-reveal].is-visible::after { transform: none; }

    /*
     * Hero entrance, once on load: the guides drop in, each line of the title
     * rises out of its mask, then the rest of the hero follows.
     */
    .hero__guides span {
      transform-origin: top;
      animation: guide-in 1400ms var(--ease-out) both;
    }

    .hero__guides span:nth-child(2) { animation-delay: 80ms; }
    .hero__guides span:nth-child(3) { animation-delay: 160ms; }
    .hero__guides span:nth-child(4) { animation-delay: 240ms; }

    .hero__line > * { animation: rise 900ms var(--ease-out) both; }
    .hero__line + .hero__line > * { animation-delay: 100ms; }

    .hero__lead { animation: lift var(--duration) var(--ease-out) 350ms both; }
    .hero__actions { animation: lift var(--duration) var(--ease-out) 450ms both; }
    .hero__facts { animation: lift var(--duration) var(--ease-out) 550ms both; }

    /*
     * On the homepage the hero title is the brand: it shrinks away as the
     * page scrolls and the header's wordmark fades in to take over. Tied to
     * scroll position, so it runs off the main thread and needs no script.
     * Browsers without scroll timelines keep the wordmark in place throughout.
     */
    @supports (animation-timeline: scroll()) {
      .hero__title {
        transform-origin: left top;
        animation: title-away linear both;
        animation-timeline: scroll(root);
        animation-range: 0 30svh;
      }

      body:has(.hero) .wordmark {
        animation: wordmark-in linear both;
        animation-timeline: scroll(root);
        animation-range: 18svh 32svh;
      }

      /* Never invisible while it has keyboard focus */
      body:has(.hero) .wordmark:focus-visible { animation: none; }

      @keyframes title-away {
        to { transform: translateY(-40%) scale(0.35); opacity: 0; }
      }

      @keyframes wordmark-in {
        from { opacity: 0; transform: translateY(0.5rem); }
      }
    }

    /* Disclosures ease open where the browser can animate to auto height;
       elsewhere they open instantly as before */
    @supports (interpolate-size: allow-keywords) {
      :root { interpolate-size: allow-keywords; }

      .disclosure::details-content {
        block-size: 0;
        overflow: hidden;
        transition:
          block-size 350ms var(--ease-out),
          content-visibility 350ms allow-discrete;
      }

      .disclosure[open]::details-content { block-size: auto; }
    }

    @keyframes guide-in {
      from { transform: scaleY(0); }
    }

    @keyframes rise {
      from { transform: translateY(105%); }
    }

    @keyframes lift {
      from { opacity: 0; transform: translateY(16px); }
    }
  }

  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    .disclosure > summary::after,
    .text-link::after,
    .site-nav ul a::after,
    .site-footer nav a::after {
      transition: none;
      animation: none;
    }
  }
}

/* ------------------------------------------------------------------ */
/* Breakpoints                                                        */
/* ------------------------------------------------------------------ */

/* Large screens: the hero fills the first screen below the header */
@media (min-width: 60.0625rem) {
  .hero { min-height: calc(100svh - var(--header-height)); }

  /* Short intros stay in view beside the longer column they introduce */
  .faq__intro,
  .contact__intro {
    position: sticky;
    top: calc(var(--header-height) + var(--space-4));
  }
}

@media (max-width: 60rem) {
  .hero__copy,
  .hero__facts { grid-column: 1 / -1; }

  .hero__facts {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--gap);
  }

  .about,
  .faq,
  .contact,
  .site-footer__inner { grid-template-columns: minmax(0, 1fr); }

  .plans { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/*
 * Navigation collapses before the links run out of room. It's collapsed from
 * the first paint, so the header never jumps when the script arrives;
 * no-js.css, loaded from a noscript tag, lays it out flat again for visitors
 * without JavaScript.
 */
@media (min-width: 70.0625rem) {
  .menu-toggle { display: none; }
}

@media (max-width: 70rem) {
  .site-nav[data-menu] {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
    padding: var(--space-3) var(--gutter) var(--space-4);
    background: var(--bg);
    border-bottom: 1px solid var(--line);
  }

  .site-nav[data-menu].is-open { display: flex; }

  .site-nav[data-menu] ul {
    flex-direction: column;
    gap: 0;
    font-size: var(--step-1);
  }

  .site-nav[data-menu] ul a {
    display: block;
    padding-block: 0.625rem;
  }

  .site-nav[data-menu] ul a::after { display: none; }
}

@media (max-width: 48rem) {

  .section-head { margin-bottom: var(--space-4); }

  .section-head,
  .services,
  .extras,
  .steps,
  .project { grid-template-columns: minmax(0, 1fr); }

  /* Stacked, the two service columns read as one list */
  .services > .disclosure-list + .disclosure-list { border-top: 0; }

  .project__title { grid-row: auto; }

  .project__desc,
  .project__meta { grid-column: 1; }
}

@media (max-width: 40rem) {
  /* Eight lines across a phone screen read as clutter */
  .hero__guides { display: none; }

  .plans { grid-template-columns: minmax(0, 1fr); }

  .hero__facts { grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }

  .compare__hint { display: block; }

  .compare-table { min-width: 36rem; }

  .compare-table tbody th { width: 8.5rem; }

  .form__row { grid-template-columns: 1fr; }
}
