/* andrewgrinde.com
   One stylesheet for every page. Quiet and editorial: black, white and one
   grey, a serif for the name and the section headings, a sans for the text,
   and one spectrum line between every section: gold, green, ice, lightening right.

   Palette. Dark only; there is no light theme.
     --black    the page
     --white    text, headings, links
     --grey     secondary text: labels, roles, notes, the footer
     --grey-ui  link underlines and field borders
     --hair     hairlines between rows (decorative, never text)
     --gold     antique gold: the current page in the nav
     --ice      light ice blue: link hover and focus rings
     --rule     the section break: gold, highlight, green, ice, lightening right
     --silver   the button fill, with --button-ink text and an ice blue to
                white --button-border
   The accents are single tokens, so a swap is one edit. Brand colors appear
   nowhere else, apart from the company logos themselves. Ratios are checked
   by tests/seo.test.mjs and listed in README.md. */

:root {
  color-scheme: dark;

  --black: #000000;
  --white: #ffffff;
  --grey: #9c9c9c;
  --grey-ui: #707070;
  --hair: #262626;
  --gold: #b39445;
  --ice: #b8dcff;

  /* The section line, matched to the header stroke: gold with its lighter
     highlight on the left, through green, through ice, lightening toward
     white on the right. Stops sit at different positions, so the blends are
     smooth and there is no hard band edge. */
  --rule: linear-gradient(
    90deg,
    #b47e35 0%,
    #e1af62 10%,
    #b47e35 24%,
    #18a882 40%,
    #18a882 52%,
    #7db9fa 74%,
    #ffffff 100%
  );
  --rule-height: 3px;

  /* The button: brushed silver with near-black text. */
  --silver: linear-gradient(180deg, #f4f5f7 0%, #d9dce1 45%, #b9bec6 55%, #e3e6ea 100%);
  --silver-dark: #b9bec6;
  --button-ink: #0b0b0c;
  --button-border: linear-gradient(90deg, var(--ice) 0%, #ffffff 50%, var(--ice) 100%);

  --tile-light: #ffffff;
  --tile-dark: #000000;

  --serif: 'Instrument Serif', 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
  --sans:
    'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
    sans-serif;

  /* Type scale, from 17px body text. */
  --step--1: 0.8125rem;
  --step-0: 1.0625rem;
  --step-1: 1.25rem;
  --step-2: clamp(1.9rem, 1.4rem + 2.2vw, 2.6rem);
  --step-3: clamp(3rem, 2rem + 5vw, 5.25rem);

  --column: 45rem;
  --measure: 65ch;
  --gutter: 20px;
  --space: clamp(64px, 9vw, 112px);
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html {
  background: var(--black);
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
  }
}

body {
  margin: 0;
  background: var(--black);
  color: var(--white);
  font: 400 var(--step-0) / 1.7 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

/* Links are white with a thin grey underline that turns ice blue on hover. */
a {
  color: var(--white);
  text-decoration: underline;
  text-decoration-color: var(--grey-ui);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: text-decoration-color 0.15s ease;
}

a:hover,
a:active {
  text-decoration-color: var(--ice);
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--ice);
  outline-offset: 3px;
}

h1,
h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  letter-spacing: -0.01em;
  line-height: 1.05;
}

h1 {
  font-size: var(--step-3);
}

h2 {
  font-size: var(--step-2);
  margin-bottom: 0.7em;
}

h3 {
  margin: 0;
  font-size: var(--step-1);
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.3;
}

p {
  margin: 0 0 1.1em;
  max-width: var(--measure);
}

strong {
  font-weight: 500;
}

.shell,
.shell--narrow {
  max-width: calc(var(--column) + 2 * var(--gutter));
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.shell .shell--narrow {
  max-width: none;
  padding: 0;
}

.skip {
  position: absolute;
  left: var(--gutter);
  top: -100px;
  padding: 8px 14px;
  background: var(--black);
  color: var(--white);
  border: 1px solid var(--white);
  text-decoration: none;
  z-index: 10;
}

.skip:focus {
  top: 12px;
}

/* Header: wordmark left, nav right. On a phone the nav wraps below. */

.site-header {
  background: var(--black);
}

.site-header__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px 28px;
  padding-top: 28px;
  padding-bottom: 28px;
}

.wordmark {
  font-family: var(--serif);
  font-size: 1.5rem;
  line-height: 1.2;
  color: var(--white);
  text-decoration: none;
  white-space: nowrap;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
  font-size: 0.9375rem;
}

.site-nav a {
  color: var(--grey);
  text-decoration: none;
  transition: color 0.15s ease;
}

.site-nav a:hover,
.site-nav a:active {
  color: var(--white);
}

.site-nav a[aria-current='page'] {
  color: var(--gold);
}

@media (max-width: 639px) {
  .site-header__row {
    padding-top: 20px;
    padding-bottom: 20px;
  }

  .site-nav {
    width: 100%;
    gap: 4px 18px;
  }
}

/* Sections. The only divider is the shared 3px edge-to-edge spectrum in
   --rule. It opens every section after the first, and the footer. The home
   hero uses the same token under the lockup. */

section {
  padding: var(--space) 0;
}

main > section + section {
  padding-top: 0;
}

main > section + section::before,
.site-footer::before {
  content: '';
  display: block;
  height: var(--rule-height);
  background: var(--rule);
}

main > section + section::before {
  margin-bottom: var(--space);
}

.hero {
  padding-top: clamp(48px, 8vw, 96px);
}

/* Home lockup only. The rule under the tagline is the same --rule as the
   section and footer lines. */
.hero .shell {
  max-width: calc(68rem + 2 * var(--gutter));
}

.hero .eyebrow {
  margin-bottom: 22px;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
}

.hero h1 {
  font-size: clamp(3.6rem, 1.6rem + 7vw, 6.75rem);
  line-height: 0.95;
  letter-spacing: -0.025em;
}

.hero__tagline {
  margin: 28px 0 0;
  max-width: 14em;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.55rem, 1.1rem + 1.7vw, 2.2rem);
  line-height: 1.35;
  letter-spacing: -0.015em;
  color: var(--white);
}

.hero__rule {
  height: var(--rule-height);
  margin: 40px 0 36px;
  background: var(--rule);
}

.hero .roles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 28px 32px;
  margin: 0;
}

.hero .roles strong {
  margin-bottom: 8px;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
}

.hero .roles a {
  font-size: 1.25rem;
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.2;
}

.hero .hero__bio {
  margin-top: 56px;
  max-width: var(--measure);
}

@media (max-width: 720px) {
  .hero .roles {
    grid-template-columns: 1fr 1fr;
  }
}

.eyebrow {
  margin: 0 0 20px;
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--grey);
}

.hero__lede {
  margin: 28px 0 24px;
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--white);
}

.hero__bio,
.page-hero p:not(.hero__lede):not(.eyebrow):not(.back):not(.page-role) {
  color: var(--grey);
}

/* About: the portrait locks to the heading. The lede sits full width under both. */
.about-intro__title {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(112px, 28vw, 220px);
  column-gap: clamp(20px, 4vw, 56px);
  align-items: end;
  margin-bottom: 28px;
}

.about-intro__title h1 {
  margin: 0;
}

.about-intro__photo {
  display: block;
  width: 100%;
  height: auto;
  justify-self: end;
}

/* Roles: small grey capitals over the company name. */
.roles {
  list-style: none;
  margin: 32px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 20px 40px;
}

.roles li {
  line-height: 1.4;
}

.roles strong,
.page-role strong {
  display: block;
  margin-bottom: 4px;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--grey);
}

/* One row that keeps the company pages a click away from the home page. */
.company-links {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 20px;
  margin-top: 36px;
}

.company-links__label {
  flex-basis: 100%;
  margin-top: 8px;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--grey);
}

.company-links__label:first-child {
  margin-top: 0;
}

/* Logo tiles. Dark tiles are black and the image fills them; Tally sits on
   white. No borders. */
.card__logo {
  display: inline-flex;
  flex: none;
  width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--tile-light);
  border: 0;
  overflow: hidden;
}

.card__logo img {
  max-width: 32px;
  max-height: 32px;
  width: auto;
  height: auto;
}

.card__logo--white {
  background: #ffffff;
  border: 0;
}

.card__logo--white img,
.card__logo--dark img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
  border-radius: inherit;
}

.card__logo--dark {
  background: var(--tile-dark);
  border: 0;
}

/* Buttons: one silver pill everywhere. A brushed silver fill inside a 2px
   border drawn as an ice blue, white, ice blue gradient. Hover
   inverts to black with white text and keeps the border. */
.button {
  display: inline-block;
  padding: 11px 26px;
  border: 2px solid transparent;
  border-radius: 999px;
  background:
    var(--silver) padding-box,
    var(--button-border) border-box;
  color: var(--button-ink);
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.4;
  text-decoration: none;
  cursor: pointer;
}

.button:hover,
.button:active {
  background:
    linear-gradient(var(--black), var(--black)) padding-box,
    var(--button-border) border-box;
  color: var(--white);
}

.button:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 3px;
}

.button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.button:disabled:hover {
  background:
    var(--silver) padding-box,
    var(--button-border) border-box;
  color: var(--button-ink);
}

.email {
  font-weight: 500;
  user-select: all;
  -webkit-user-select: all;
}

/* Footer */

.site-footer {
  padding: 0 0 56px;
  font-size: 0.875rem;
  color: var(--grey);
}

.site-footer::before {
  margin-bottom: 26px;
}

.site-footer__row {
  display: grid;
  gap: 14px;
}

.site-footer p {
  margin: 0;
}

.site-footer__row > p:last-child {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
}

.site-footer a {
  color: var(--grey);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s ease;
}

.site-footer a:hover,
.site-footer a:active {
  color: var(--white);
}

/* Rows: theme items and company entries, separated by grey hairlines. */

.theme-list,
.entries {
  list-style: none;
  margin: 48px 0 0;
  padding: 0;
}

.theme,
.entry {
  padding: 32px 0;
  border-top: 1px solid var(--hair);
}

.theme h3 {
  margin-bottom: 10px;
}

.theme p,
.entry p {
  margin: 0 0 10px;
  color: var(--grey);
}

.theme .theme__links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
  margin: 14px 0 0;
  font-size: 0.9375rem;
}

.theme__links a,
.company-links a {
  color: var(--white);
}

.themes__also {
  margin: 32px 0 0;
  color: var(--grey);
}

.entry {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  gap: 24px;
  scroll-margin-top: 24px;
}

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

@media (max-width: 559px) {
  .entry {
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
  }
}

.entry h3 {
  margin: 4px 0 6px;
}

.entry .entry__tag {
  margin: 0 0 12px;
  color: var(--white);
}

.entry .entry__link {
  margin: 16px 0 0;
  font-size: 0.9375rem;
}

/* The subtle arrow on every row's outbound link. */
.entry__link a::after {
  content: '\2009\2192';
  display: inline-block;
  color: var(--grey);
  transition: transform 0.15s ease;
}

.entry__link a:hover::after {
  transform: translateX(3px);
}

/* Principles and steps: spaced, not boxed. */

.principles {
  margin: 32px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 24px;
  max-width: var(--measure);
}

ol.principles {
  counter-reset: step;
}

.principles li {
  color: var(--grey);
}

.principles strong {
  display: block;
  margin-bottom: 2px;
  color: var(--white);
  font-weight: 500;
}

ol.principles li {
  position: relative;
  padding-left: 36px;
}

ol.principles li::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0.15em;
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
  color: var(--grey);
}

.long-game__cta {
  margin: 36px 0 0;
}

/* Company and project pages */

.page-hero h1 {
  display: flex;
  align-items: center;
  gap: 18px;
}

.page-hero__mark {
  flex: none;
  width: 44px;
  height: 44px;
  padding: 4px;
  border-radius: 9px;
  background: var(--tile-light);
  border: 0;
  object-fit: contain;
}

.page-hero__mark--dark {
  padding: 0;
  background: var(--tile-dark);
  border: 0;
  object-fit: cover;
}

.back {
  margin: 0 0 40px;
  font-size: 0.875rem;
}

.back a {
  color: var(--grey);
  text-decoration: none;
  transition: color 0.15s ease;
}

.back a::before {
  content: '\2190\2009';
}

.back a:hover,
.back a:active {
  color: var(--white);
}

.page-role {
  margin: 32px 0 0;
  color: var(--white);
}

.page-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 20px;
  align-items: center;
  margin: 40px 0 0;
}

/* Contact form */

.contact-form {
  display: grid;
  gap: 24px;
  margin: 0;
  max-width: var(--measure);
}

.field {
  display: grid;
  gap: 8px;
  margin: 0;
}

.field label {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--grey);
}

.field__optional {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}

.field input,
.field textarea {
  width: 100%;
  min-width: 0;
  padding: 12px 14px;
  font: inherit;
  color: var(--white);
  background: var(--black);
  border: 1px solid var(--grey-ui);
  border-radius: 0;
}

.field input:hover,
.field textarea:hover {
  border-color: var(--grey);
}

.field textarea {
  resize: vertical;
  min-height: 180px;
}

.field input:focus-visible,
.field textarea:focus-visible {
  outline-offset: 2px;
  border-color: var(--white);
}

/* The trap field is for bots. People never see it or reach it. */
.field--trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.turnstile {
  min-height: 0;
  max-width: 100%;
  overflow: hidden;
}

.contact-form__actions {
  margin: 8px 0 0;
}

.contact-form__status {
  margin: 0;
  min-height: 1.7em;
  color: var(--grey);
}

.contact-offline {
  font-size: var(--step-1);
  line-height: 1.55;
}

.contact-note {
  margin-top: 40px;
  color: var(--grey);
  font-size: 0.9375rem;
}

/* Development page */

.approach h3 {
  margin: 48px 0 0;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--grey);
}

.approach h3 + .principles {
  margin-top: 20px;
}

/* Company rows on the home and Companies pages. */

.entry__role {
  margin: 0 0 4px;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--grey);
}

.entry h3 a {
  text-decoration: none;
}

.entry h3 a:hover {
  text-decoration: underline;
}

.entry .entry__links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
  margin: 14px 0 0;
  font-size: 0.9375rem;
}

.entry__links a:last-child::after {
  content: '\2009\2197';
  color: var(--grey);
}

.entry .entry__status,
.entry .entry__meta {
  margin: 0 0 10px;
  font-size: 0.9375rem;
  color: var(--grey);
}

.sub-entries {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 10px;
  color: var(--grey);
}

.sub-entries li {
  padding-left: 0;
}

.sub-entries a:not(.site-link) {
  color: var(--white);
}

.site-link {
  font-size: 0.875rem;
  color: var(--grey);
}

.section__more {
  margin: 32px 0 0;
  color: var(--grey);
}

/* Areas of interest and topic lists: two columns of plain rows. */

.interest-list,
.topic-list {
  list-style: none;
  margin: 32px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
  column-gap: 32px;
}

.interest-list li,
.topic-list li {
  padding: 14px 0;
  border-top: 1px solid var(--hair);
}

.topic-list li {
  color: var(--grey);
}

.interest-list a {
  text-decoration: none;
}

.interest-list a:hover {
  text-decoration: underline;
}

.link-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
}

/* Facts on the company pages: label over value, split by hairlines. */

.facts {
  margin: 32px 0 0;
}

.facts > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 4px;
  padding: 18px 0;
  border-top: 1px solid var(--hair);
}

@media (min-width: 640px) {
  .facts > div {
    grid-template-columns: 180px minmax(0, 1fr);
    gap: 24px;
  }
}

.facts dt {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--grey);
  padding-top: 0.3em;
}

.facts dd {
  margin: 0;
  max-width: var(--measure);
}

/* Essays. Long-form reading: the body column holds 65 characters. */

.essay__meta,
.essay__topics,
.essay__notice {
  color: var(--grey);
  font-size: 0.9375rem;
}

.essay__body {
  padding-bottom: var(--space);
}

.essay__body h2 {
  margin-top: 1.6em;
}

.essay__body h3 {
  margin: 1.8em 0 0.6em;
}

.essay__body ul,
.essay__body ol {
  max-width: var(--measure);
  padding-left: 1.2em;
}

.essay__body blockquote {
  margin: 1.6em 0;
  padding-left: 20px;
  border-left: 1px solid var(--grey-ui);
  color: var(--grey);
}

.essay__footer {
  padding-bottom: var(--space);
}

.essay__footer h2 {
  font-size: var(--step-1);
  margin-top: 1.4em;
}

/* Footer: page links, then the company sites. */

.site-footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  margin: 0;
}
