/* Stanquette — streamline moderne, restrained Americana.
   Full-bleed color bands, hairline-separated rows, sharp corners.
   No cards, no rounded anything, no ornament.

   This file is site composition only. Tokens, reset/typography and the
   interactive components live in design/ and load ahead of it. */

/* --- Bands ---------------------------------------------------------------
   Every top-level section is a full-bleed band with a centered measure. */

.band {
  padding: var(--band-pad) var(--gutter);

  & > * {
    max-width: var(--measure-wide);
    margin-inline: auto;
  }

  &.band--ink {
    background: var(--ink);
    color: var(--cream);
  }

  &.band--dune {
    background: var(--sand-deep);
  }

  &.band--orange {
    background: var(--orange);
    color: var(--cream);
  }
}

.section-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-section);
  font-weight: var(--weight-regular);
  line-height: var(--leading-hero);
  letter-spacing: var(--track-display);
  text-wrap: balance;
}

.section-lede {
  margin: 0.75rem 0 0;
  max-width: var(--measure-lede);
  color: var(--ink-soft);

  .band--ink & {
    color: var(--ink-soft-on-ink);
  }
}

.section-head {
  display: grid;
  gap: 0.875rem;
  margin-bottom: clamp(1.75rem, 3vw, 2.75rem);

  @media (width >= 56rem) {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 4rem;
    align-items: end;

    & .section-lede {
      margin: 0;
      justify-self: end;
    }
  }
}

/* --- Masthead ------------------------------------------------------------ */

.site-masthead {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  align-items: center;
  justify-content: space-between;
  padding: 1rem var(--gutter);
  background: var(--ink);
  color: var(--cream);

  & .wordmark {
    width: 6.875rem;

    @media (width >= 48rem) {
      width: 10.625rem;
    }
  }
}

.masthead-nav {
  display: flex;
  gap: clamp(1.25rem, 4vw, 2rem);
  align-items: center;

  & a {
    color: var(--cream);
    font-family: var(--font-body);
    font-size: var(--step-small);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    padding-bottom: 0.1rem;
    transition: color var(--tempo) var(--ease),
      border-color var(--tempo) var(--ease);

    &:hover,
    &:focus-visible {
      color: var(--orange-tint);
      border-bottom-color: var(--orange-tint);
    }

    &[aria-current="page"] {
      border-bottom-color: var(--orange);
    }
  }
}

/* The home page opens on the hero wordmark at full size, so the masthead drops
   its slab and its miniature copy of the mark and leaves only the nav. */
.site-masthead--bare {
  background: none;
  color: var(--ink);
  justify-content: flex-end;

  & > a:has(> .wordmark) {
    display: none;
  }

  & .masthead-nav a {
    color: var(--ink);

    &:hover,
    &:focus-visible {
      color: var(--orange);
      border-bottom-color: var(--orange);
    }
  }
}

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

.hero {
  display: grid;
  justify-items: center;
  gap: 1.375rem;
  padding: clamp(2.5rem, 7vw, 4.75rem) var(--gutter) clamp(2.5rem, 6vw, 4rem);
  text-align: center;

  & .wordmark {
    width: min(100%, 56.25rem);
    color: var(--ink);
  }
}

.hero-tagline {
  margin: 0;
  max-width: 40rem;
  font-size: var(--step-name);
  color: var(--ink-soft);
}

.hero-actions,
.cta-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.875rem;
  justify-content: center;
  margin-top: 0.625rem;
}

/* --- Rule lists ----------------------------------------------------------
   The one repeating structure on the site: a heavy rule opens the list,
   hairlines separate the rows. Used for values, packages, work, invoices. */

.rule-list {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: var(--rule-heavy) solid var(--ink);

  .band--ink & {
    border-top-color: var(--cream);
  }
}

.rule-list-item {
  display: grid;
  gap: 0.375rem;
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--rule-hair);

  .band--ink & {
    border-bottom-color: var(--rule-hair-on-ink);
  }

  @media (width >= 56rem) {
    grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
    gap: 2.5rem;
    align-items: baseline;
  }
}

.item-name {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-title);
  font-weight: var(--weight-regular);
  line-height: var(--leading-title);
  color: inherit;
}

.item-body {
  margin: 0;
  color: var(--ink-soft);

  .band--ink & {
    color: var(--ink-soft-on-ink);
  }

  .band--dune & {
    color: var(--ink-soft-on-dune);
  }
}

/* Rows that are entirely a link (goodies, packages). The link carries the
   columns here, so the row must not also be a grid — otherwise the link is
   confined to the row's first track and its own columns collapse inside it. */
.rule-list-item:has(> .item-link) {
  display: block;
  padding: 0;

  & .item-link {
    display: grid;
    gap: 0.375rem;
    padding: 1.25rem 0;
    color: inherit;
    text-decoration: none;

    /* Most of these lists mix linked rows with unlinked ones, so a row cannot
       rely on hover to admit it is a link. The name carries the same hairline
       underline prose links do. */
    & .item-name {
      text-decoration: underline;
      text-decoration-thickness: 1px;
      text-underline-offset: 3px;
      text-decoration-color: color-mix(in oklab, currentColor 35%, transparent);
    }
    transition: background-color var(--tempo) var(--ease),
      padding-inline var(--tempo) var(--ease);

    @media (width >= 56rem) {
      grid-template-columns: minmax(0, 22rem) minmax(0, 1fr) auto;
      gap: 2.5rem;
      align-items: baseline;
    }

    /* Narrow rows stack, and a lone arrow on its own line reads as debris —
       the whole row is the tap target there anyway. */
    & .item-arrow {
      display: none;
      color: var(--orange-deep);
      font-size: 1.25rem;
      line-height: 1;
      transition: transform var(--tempo-slow) var(--ease);

      @media (width >= 56rem) {
        display: block;
      }
    }

    /* A row that leads somewhere names its destination. It takes the column the
       bare arrow would take, and unlike the arrow it stays put on narrow
       screens — that is where the affordance is needed most. */
    & .item-cue {
      display: flex;
      gap: 0.4em;
      align-items: baseline;
      font-family: var(--font-label);
      font-size: var(--step-label);
      font-weight: var(--weight-semibold);
      letter-spacing: var(--track-caps);
      text-transform: uppercase;
      color: var(--orange-deep);
      white-space: nowrap;

      & span {
        transition: transform var(--tempo-slow) var(--ease);
      }
    }

    &:hover,
    &:focus-visible {
      & .item-name {
        color: var(--orange-deep);
        text-decoration-thickness: 2px;
        text-decoration-color: currentColor;
      }

      & .item-arrow,
      & .item-cue span {
        transform: translateX(0.25rem);
      }
    }
  }
}

/* Larger name for the open-source list */
.rule-list--goodies .item-name {
  font-size: var(--step-name);
}

/* --- CTA band ------------------------------------------------------------ */

.cta-band {
  display: grid;
  justify-items: center;
  gap: 1.125rem;
  text-align: center;

  & .cta-title {
    margin: 0;
    max-width: 22ch;
    font-family: var(--font-display);
    font-size: var(--step-display);
    font-weight: var(--weight-regular);
    line-height: var(--leading-display);
    text-wrap: balance;
  }

  & .cta-lede {
    margin: 0;
    max-width: 44ch;
    font-size: var(--step-lede);
    color: color-mix(in srgb, var(--cream) 90%, transparent);
  }
}

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

.site-footer {
  padding: clamp(2.5rem, 5vw, 4rem) var(--gutter) 2.75rem;
  background: var(--ink);
  color: var(--cream);

  & > * {
    max-width: var(--measure-wide);
    margin-inline: auto;
  }
}

.footer-top {
  display: grid;
  gap: 2rem;

  @media (width >= 48rem) {
    grid-template-columns: minmax(0, 1fr) auto auto;
    gap: 5rem;
    justify-content: space-between;
  }
}

.footer-brand {
  display: grid;
  gap: 0.875rem;
  justify-items: start;

  & .wordmark {
    width: 13.75rem;
  }

  & p {
    margin: 0;
    max-width: 24rem;
    color: var(--ink-soft-on-ink);
  }
}

.footer-nav {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.5rem;

  & .footer-nav-title {
    font-family: var(--font-label);
    font-size: var(--step-label);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--track-label);
    color: var(--orange-tint);
    margin-bottom: 0.125rem;
  }

  & a {
    color: var(--cream);
    font-size: var(--step-small);
    text-decoration: none;
    border-bottom: 1px solid transparent;

    &:hover,
    &:focus-visible {
      color: var(--orange-tint);
      border-bottom-color: var(--orange-tint);
    }
  }
}

.footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.625rem 1.5rem;
  align-items: center;
  justify-content: space-between;
  margin-top: clamp(2rem, 4vw, 3.5rem);
  padding-top: 1.375rem;
  border-top: 1px solid var(--rule-hair-on-ink);
  font-family: var(--font-label);
  font-size: var(--step-label);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-legal);
  color: var(--text-muted-on-ink);

  & a {
    color: inherit;
    text-decoration: none;

    &:hover,
    &:focus-visible {
      color: var(--orange-tint);
    }
  }
}

/* --- Article pages (hire) ------------------------------------------------ */

.page-head {
  padding: clamp(2rem, 5vw, 3.5rem) var(--gutter) clamp(2rem, 4vw, 3rem);

  & > * {
    max-width: var(--measure-wide);
    margin-inline: auto;
  }
}

.page-head-inner {
  display: grid;
  gap: 2rem;
  padding-top: clamp(1.75rem, 3vw, 2.75rem);
  border-top: var(--rule-heavy) solid var(--ink);

  @media (width >= 56rem) {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: 4rem;
  }
}

/* Case studies lead with a title and a lede and nothing else, so the head is
   one column. The heavy rule still spans the wide measure — the text under it
   sits at prose measure, flush left with the body below. */
.page-head-solo {
  padding-top: clamp(1.75rem, 3vw, 2.75rem);
  border-top: var(--rule-heavy) solid var(--ink);

  & > * {
    max-width: var(--measure-prose);
  }
}

.page-title {
  margin: 0 0 0.875rem;
  font-family: var(--font-display);
  font-size: var(--step-display);
  font-weight: var(--weight-regular);
  line-height: var(--leading-hero);
  text-wrap: balance;
}

.page-lede {
  margin: 0;
  font-size: var(--step-lede);
  color: var(--ink-soft);
}

/* Key/value strip: role, location, stack, availability */
.page-meta {
  margin: 0;
  display: grid;

  & > div {
    display: grid;
    gap: 0.125rem;
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--rule-hair);

    &:first-child {
      padding-top: 0;
    }
  }

  & dt {
    font-family: var(--font-label);
    font-size: var(--step-label);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--track-label);
    color: var(--orange-deep);
  }

  & dd {
    margin: 0;
    font-size: var(--step-small);
  }
}

.article-body {
  padding: 0 var(--gutter) clamp(3rem, 6vw, 4.5rem);

  & > * {
    max-width: var(--measure-wide);
    margin-inline: auto;
  }
}

.article-layout {
  display: grid;
  gap: 2.5rem;

  /* A grid item defaults to min-width:auto, so anything that refuses to wrap —
     a code block, a wide table — drags the whole column wider than the screen.
     The desktop track says minmax(0, …) for the same reason; single-column
     mobile has no track to say it on, so the children say it themselves. */
  & > * {
    min-width: 0;
  }

  @media (width >= 64rem) {
    grid-template-columns: 12rem minmax(0, 1fr);
    gap: 4rem;
    align-items: start;
  }
}

.contents-rail {
  font-family: var(--font-label);
  font-size: var(--step-small);

  @media (width >= 64rem) {
    position: sticky;
    top: 2rem;
  }

  & .contents-title {
    padding-top: 0.75rem;
    border-top: var(--rule-heavy) solid var(--ink);
    font-size: var(--step-label);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--track-label);
    color: var(--ink-soft);
    margin-bottom: 0.875rem;
  }

  & ol {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 0.5rem;
  }

  & a {
    color: var(--ink);
    font-size: var(--step-fine);
    text-decoration: none;
    border-bottom: 1px solid transparent;

    &:hover,
    &:focus-visible {
      color: var(--orange-deep);
      border-bottom-color: var(--orange-deep);
    }
  }
}

/* Two-column key list inside prose (technical expertise). The columns share
   the parent's rows via subgrid, so every heading sits in one band and every
   list starts on the same line no matter how the headings wrap. */
.column-list {
  display: grid;
  gap: 2rem;
  margin: 1.5rem 0 0;

  @media (width >= 40rem) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: auto auto;

    & > div {
      display: grid;
      grid-row: span 2;
      grid-template-rows: subgrid;
      gap: 0.625rem;
    }
  }

  & .column-title {
    /* Bottom-aligned so a one-line heading keeps its baseline with the last
       line of a heading that wrapped. */
    align-self: end;
    margin: 0 0 0.625rem;
    font-family: var(--font-label);
    font-size: var(--step-label);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--track-label);
    color: var(--ink-soft);

    @media (width >= 40rem) {
      margin-bottom: 0;
    }
  }

  & ul {
    margin-bottom: 0;
  }
}

/* --- Kitchen sink -------------------------------------------------------- */

.kitchen-section {
  padding: clamp(2.5rem, 5vw, 3.375rem) var(--gutter) 0;

  & > * {
    max-width: var(--measure-wide);
    margin-inline: auto;
  }

  & > .section-title {
    margin-bottom: 1.125rem;
  }

  & > .kitchen-rule {
    height: var(--rule-heavy);
    background: var(--ink);
    margin-bottom: 2rem;
  }

  /* `margin-block`, not `margin`. A kitchen note is a direct child of the
     section, where the shorthand's zero inline margin outranks — same
     specificity, later in the file — the `margin-inline: auto` two rules up,
     and the note alone slid to the left gutter while the title, the rule and
     the grid stayed on the measure.

     The line length is then capped with padding rather than `max-width`: the
     note keeps the band's own box, so it starts on the same left edge as the
     title above it, and only the text stops short. A narrower box would have
     centered itself inside the band and left the title behind. */
  & > .kitchen-note {
    margin-block: 0 1.75rem;
    padding-inline-end: max(
      0px,
      min(var(--measure-wide), 100%) - var(--measure-prose)
    );
    color: var(--ink-soft);
  }
}

.kitchen-grid {
  display: grid;
  gap: 1.875rem;

  @media (width >= 48rem) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  @media (width >= 64rem) {
    grid-template-columns: repeat(var(--columns, 3), minmax(0, 1fr));
  }

  /* Specimens are a single row of columns, so they share the grid's rows: the
     captions line up even when one specimen's swatch is taller than another's. */
  @media (width >= 48rem) {
    &:has(> .specimen) {
      grid-template-rows: auto auto;
      row-gap: 0.75rem;

      & > .specimen {
        grid-row: span 2;
        grid-template-rows: subgrid;
      }
    }
  }
}

/* A labeled specimen: the thing itself, with a caption underneath */
.specimen {
  display: grid;
  gap: 0.75rem;
  align-content: start;

  & .specimen-label {
    font-family: var(--font-label);
    font-size: var(--step-label);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--track-caps);
    text-transform: uppercase;
    color: var(--ink-soft);
  }

  & .specimen-caption {
    margin: 0;
    font-size: var(--step-small);
    line-height: var(--leading-control);
    color: var(--ink-soft);
  }
}

/* Button matrix: one variant per row, one state per column */
.button-matrix {
  display: grid;
  border-top: var(--rule-heavy) solid var(--ink);

  & .button-row {
    display: grid;
    gap: 1.25rem;
    padding: 1.5rem 0;
    border-bottom: 1px solid var(--rule-hair);

    @media (width >= 64rem) {
      grid-template-columns: 9rem repeat(4, minmax(0, 1fr));
      gap: 1.5rem;
      align-items: start;
    }
  }

  & .button-row-name {
    font-family: var(--font-display);
    font-size: var(--step-title);
    font-weight: var(--weight-regular);
  }

  & .button-cell {
    display: grid;
    gap: 0.625rem;
    justify-items: start;
  }
}

/* The kitchen sink shows disabled/hover/active as static specimens, so the
   states need to be forced rather than waited for. */
.is-hover.button--primary {
  background: var(--orange-hover);
  box-shadow: var(--lift-primary-hover);
}

.is-active.button--primary {
  background: var(--orange-press);
  box-shadow: var(--lift-primary-press);
}

.is-hover.button--secondary {
  background: var(--ink-hover);
  box-shadow: var(--lift-secondary-hover);
}

.is-active.button--secondary {
  background: var(--ink-press);
  box-shadow: var(--lift-secondary-press);
}

.is-hover.button--quiet {
  background: var(--cream);
  box-shadow: var(--lift-quiet-hover);
}

.is-active.button--quiet {
  background: var(--sand-press);
  box-shadow: var(--lift-quiet-press);
}

.is-hover.button--destructive {
  background: var(--orange-wash);
  box-shadow: var(--lift-destructive-hover);
}

.is-active.button--destructive {
  background: var(--orange-wash-press);
  box-shadow: var(--lift-destructive-press);
}

/* Focus cannot be photographed, so the specimen forces it. Border color
   only: the box keeps exactly the same size, so nothing reflows. */
.is-focus.field-control,
.is-focus.code-box {
  border-color: var(--orange);
}

.badge-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.notice-stack {
  display: grid;
  gap: 0.875rem;
}
