/*
  methanerain house style.

  Ground, surface, raised, the three text weights, the line colours and all
  three radii are the same numbers adscheduler.io ships with, on purpose: this
  page and that product come from the same shop, and reusing the tokens is what
  makes that legible rather than asserted.

  What is methanerain's own is the accent, an amber core. Seatbooker owns
  violet, AdScheduler owns volt green and the DBA blog owns cyan, and a parent
  page wearing any of them would read as one of its own sites rather than the
  company above them. Those three colours appear here only as citations, beside
  their own site's name, and nowhere else.

  Two modes. The dark set is the house set above. The light set is built on the
  same near-neutral family so the two read as one design rather than two, and
  every step of the text ramp was checked against its own ground rather than
  assumed:

    dark   fg    #f2f3f4 on #0a0b0d ....... 17.72:1
    dark   muted #a8adb5 on #0a0b0d ........ 8.73:1
    dark   faint #7a8089 on #0a0b0d ........ 4.95:1   (the floor)
    light  fg    #16181c on #fbfbfc ....... 17.19:1
    light  muted #52565e on #fbfbfc ........ 7.12:1
    light  faint #6b7079 on #fbfbfc ........ 4.81:1   (the floor)

  The accent needs a second value in light mode and only in light mode. Pure
  #f2a93c on a white ground is 1.9:1, which cannot legally hold text, so
  `--accent-ink` is the same hue held darker for text and borders while
  `--accent` stays the untouched brand value driving fills and the mark. This
  is the pattern Seatbooker already uses for its own brand orange, where the
  logo keeps #F57C00 and the UI token is a darkened counterpart.

    dark   accent     #f2a93c on #0a0b0d ............. 9.86:1
    light  accent-ink hsl(36 96% 29%) on #fbfbfc ..... 5.64:1
    both   #0a0b0d text on the #f2a93c button fill ... 9.86:1

  The primary button is an amber fill with near-black text in both modes, so
  the one thing a visitor is meant to press looks identical either way.

  Shape scale, one rule applied everywhere: media wells and grouped lists are
  --radius-lg, controls and marks are --radius-md, small chips are
  --radius-sm. No pills.
*/

@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/barlow-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/barlow-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/barlow-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/barlow-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/barlow-800.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/plexmono-500.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/plexmono-600.woff2') format('woff2');
}

:root {
  /* Brand values. Mode independent, and the accent is the one methanerain
     owns. Nothing below is allowed to redefine these three. */
  --accent: #f2a93c;
  --seatbooker: #6a4cff;  /* Seatbooker's own brand violet, cited not claimed */
  --adscheduler: #c4f24b; /* AdScheduler's own volt green, cited not claimed */
  --johnmccormack: #3ea8c4; /* The DBA blog's cyan, same citation rule */

  /* Shape scale, shared with adscheduler.io. */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 14px;

  --nav-h: 4.25rem;

  --sans: 'Barlow', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;

  /* Type ramp. One clamp per step rather than a size picked per section. */
  --step-display: clamp(2.4rem, 5.2vw, 3.9rem);
  --step-h2: clamp(1.75rem, 3.2vw, 2.4rem);
  --step-h3: 1.3rem;
  --step-lead: clamp(1.05rem, 1.5vw, 1.19rem);
  --step-body: 1rem;
  --step-small: 0.88rem;

  /* Vertical rhythm. Two numbers, not one per section. */
  --section-y: 5.5rem;
  --section-y-tight: 3.5rem;
}

/* Dark is the default, full stop, which keeps this page in step with
   adscheduler.io. The OS preference is not consulted: `prefers-color-scheme`
   would override the brand's own starting position, and the toggle in the
   header is the thing that decides instead. Its choice persists in
   localStorage and is applied to <html data-theme> before first paint. */
:root {
  --ground: #0a0b0d;
  --surface: #141619;
  --raised: #1d2025;

  --fg: #f2f3f4;
  --muted: #a8adb5;
  --faint: #7a8089;

  --line: rgba(255, 255, 255, 0.1);
  --line-strong: rgba(255, 255, 255, 0.18);

  --accent-ink: var(--accent);
  --on-accent: #0a0b0d;

  --shadow: 0 18px 48px rgba(0, 0, 0, 0.45);
  color-scheme: dark;
}

:root[data-theme="light"] {
  --ground: #fbfbfc;
  --surface: #f2f3f5;
  --raised: #e9ebee;

  --fg: #16181c;
  --muted: #52565e;
  --faint: #6b7079;

  --line: rgba(10, 11, 13, 0.12);
  --line-strong: rgba(10, 11, 13, 0.2);

  /* Same hue as the brand amber, held dark enough to carry text. */
  --accent-ink: hsl(36 96% 29%);
  --on-accent: #0a0b0d;


  /* Tinted to the ground rather than pure black, so the shadow belongs to
     the page it sits on. */
  --shadow: 0 18px 40px rgba(10, 11, 13, 0.1);
  color-scheme: light;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--fg);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3 {
  margin: 0;
  font-weight: 800;
  letter-spacing: -0.02em;
}

p { margin: 0; }

img, svg { display: block; }

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

:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

.container {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* Skip link. The page is short, but the nav is repeated at top and bottom and
   a keyboard user should not have to walk it twice. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  padding: 0.7rem 1rem;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  border-radius: var(--radius-md);
}

.skip-link:focus {
  left: 1rem;
  top: 1rem;
}

/* ---- Nav ---- */

.site-header {
  height: var(--nav-h);
  display: flex;
  align-items: center;
  border-bottom: 1px solid var(--line);
}

.site-header .container {
  display: flex;
  align-items: center;
  gap: 2rem;
  width: 100%;
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.wordmark img {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
}

.wordmark span {
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--fg);
}

.site-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 1.75rem;
  white-space: nowrap;
}

.site-nav a {
  font-size: var(--step-small);
  font-weight: 600;
  color: var(--muted);
  transition: color 0.15s ease;
}

.site-nav a:hover {
  color: var(--fg);
}

/*
  Hidden until the inline script in <head> confirms JS ran, because without it
  the button cannot do anything and a control that does nothing is worse than
  no control. Square, --radius-md, same shape rule as every other control.
*/
.theme-toggle {
  display: none;
  padding: 0;
  width: 34px;
  height: 34px;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.js .theme-toggle {
  display: inline-flex;
}

.theme-toggle:hover {
  color: var(--fg);
  border-color: var(--line-strong);
}

.theme-toggle svg {
  width: 17px;
  height: 17px;
}

/* Each theme shows the one it will switch you to. */
:root[data-theme="dark"] .icon-moon,
:root[data-theme="light"] .icon-sun {
  display: none;
}

/* ---- Buttons ---- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  padding: 0.72rem 1.15rem;
  border-radius: var(--radius-md);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: transform 0.15s cubic-bezier(0.2, 0.7, 0.3, 1),
              background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.btn-primary {
  background: var(--accent);
  color: var(--on-accent);
}

.btn-primary:hover {
  transform: translateY(-1px);
}

.btn-secondary {
  border-color: var(--line-strong);
  color: var(--fg);
}

.btn-secondary:hover {
  border-color: var(--fg);
  transform: translateY(-1px);
}

/* Physical push on press, in both variants. */
.btn:active {
  transform: scale(0.98);
}

@media (prefers-reduced-motion: reduce) {
  .btn,
  .btn:hover,
  .btn:active {
    transform: none;
  }
}

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

.hero {
  padding-top: 4.5rem;
  padding-bottom: var(--section-y);
  display: grid;
  grid-template-columns: 1.25fr 0.75fr;
  gap: 4rem;
  align-items: center;
}

.hero h1 {
  font-size: var(--step-display);
  line-height: 1.04;
  max-width: 15ch;
}

.hero-lead {
  margin-top: 1.4rem;
  max-width: 44ch;
  font-size: var(--step-lead);
  color: var(--muted);
  line-height: 1.6;
}

.hero-actions {
  margin-top: 2rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

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

.hero-art {
  display: flex;
  justify-content: center;
}

.hero-art svg {
  width: 100%;
  max-width: 300px;
  height: auto;
}

.rain-trail {
  stroke: var(--fg);
  opacity: 0.34;
}

.rain-lead {
  stroke: var(--accent);
  opacity: 1;
}

/*
  The one piece of decorative motion on the page, and it is on the mark rather
  than on anything a person is trying to read. It earns its place by making the
  mark perform the name: the strokes fall. Travel is 14/34, the same slant the
  strokes are drawn at, so they move along their own axis rather than across it.
*/
@media (prefers-reduced-motion: no-preference) {
  .rain-trail,
  .rain-lead {
    animation: fall var(--dur, 9s) linear var(--delay, 0s) infinite;
  }
}

@keyframes fall {
  0% {
    transform: translate(-14px, -34px);
    opacity: 0;
  }
  24%, 76% {
    opacity: var(--peak, 0.34);
  }
  100% {
    transform: translate(14px, 34px);
    opacity: 0;
  }
}

.rise {
  animation: rise 0.6s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}

.rise-delay {
  animation: rise 0.6s cubic-bezier(0.2, 0.7, 0.3, 1) 0.1s both;
}

@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/*
  Sections arrive as the reader reaches them, which is the only thing this
  animation is for: it marks where one block ends and the next begins on a page
  with no dividers between them. Set by script.js, which adds .is-in when the
  section intersects. No JS, no observer support, or reduced motion, and the
  content is simply visible.
*/
.reveal {
  opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.55s cubic-bezier(0.2, 0.7, 0.3, 1),
                transform 0.55s cubic-bezier(0.2, 0.7, 0.3, 1);
  }

  .js .reveal.is-in {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .rise,
  .rise-delay {
    animation: none;
  }
}

/* ---- Section furniture ---- */

.section {
  border-top: 1px solid var(--line);
  padding-top: var(--section-y);
  padding-bottom: var(--section-y);
}

.section h2 {
  font-size: var(--step-h2);
  line-height: 1.1;
  max-width: 18ch;
}

.section-lead {
  margin-top: 1.1rem;
  max-width: 56ch;
  color: var(--muted);
  font-size: var(--step-lead);
  line-height: 1.6;
}

/* ---- What we build ---- */

/*
  Definition rows rather than a card grid. Three items do not need three boxes,
  and the narrow-label / wide-body split gives the section a shape the hero and
  the product rows do not already have. One hairline between rows, none above
  the first or below the last.
*/
.build-list {
  margin-top: 3rem;
  display: flex;
  flex-direction: column;
}

.build-row {
  display: grid;
  grid-template-columns: minmax(0, 0.42fr) minmax(0, 1fr);
  gap: 2.5rem;
  padding: 2rem 0;
}

.build-row + .build-row {
  border-top: 1px solid var(--line);
}

/* The row's own padding is for the space between rows, not for the space at
   the ends of the list, which the section already owns. */
.build-row:first-child { padding-top: 0; }
.build-row:last-child { padding-bottom: 0; }

.build-row h3 {
  font-size: var(--step-h3);
  line-height: 1.25;
}

.build-row p {
  color: var(--muted);
  line-height: 1.62;
  max-width: 54ch;
}

/* ---- Products ---- */

.product-list {
  margin-top: 3rem;
}

.product {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: 3.5rem;
  align-items: center;
  padding: 3.25rem 0;
}

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

.product:first-child { padding-top: 0; }
.product:last-child { padding-bottom: 0; }

/* The second row mirrors the first so the pair reads as a pair rather than as
   two of the same row. Two is the whole set, so the alternation stops here. */
.product-flip .product-media {
  order: -1;
}

.product-head {
  display: flex;
  align-items: center;
  gap: 0.85rem;
}

.product-mark {
  width: 46px;
  height: 46px;
  border-radius: var(--radius-md);
  flex-shrink: 0;
}

.product-head h3 {
  font-size: 1.45rem;
}

.product-copy p {
  margin-top: 1.1rem;
  color: var(--muted);
  line-height: 1.62;
  max-width: 46ch;
}

.product-link {
  margin-top: 1.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--mono);
  font-size: var(--step-small);
  font-weight: 500;
  color: var(--accent-ink);
  transition: gap 0.15s ease;
}

.product-link svg {
  width: 13px;
  height: 13px;
  transition: transform 0.15s ease;
}

.product-link:hover svg {
  transform: translate(2px, -2px);
}

/* A product whose domain is not live yet. Same type and rhythm as a real
   product link, with the accent and the arrow dropped, because both of those
   promise somewhere to go. Remove once every product links out. */
.product-link.is-pending {
  color: var(--faint);
}

.product-link .badge {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.1rem 0.45rem;
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--muted);
}

.product-media {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow);
  transition: transform 0.25s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.product-media img {
  display: block;
  width: 100%;
  height: auto;
}

.product:hover .product-media {
  transform: translateY(-3px);
}

@media (prefers-reduced-motion: reduce) {
  .product-media,
  .product:hover .product-media {
    transition: none;
    transform: none;
  }
}

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

.site-footer {
  border-top: 1px solid var(--line);
  padding: 2.5rem 0;
}

.site-footer .container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.75rem;
}

.site-footer .wordmark span {
  font-size: 0.92rem;
}

.site-footer .wordmark img {
  width: 22px;
  height: 22px;
}

.footer-note {
  color: var(--faint);
  font-size: var(--step-small);
}

.footer-links {
  margin-left: auto;
  display: flex;
  gap: 1.5rem;
}

.footer-links a {
  font-size: var(--step-small);
  font-weight: 600;
  color: var(--muted);
  transition: color 0.15s ease;
}

.footer-links a:hover {
  color: var(--fg);
}

/* Sits in the same row as the links but is not one: no hover, no accent. */
.footer-links span {
  font-size: var(--step-small);
  font-weight: 600;
  color: var(--faint);
}

/* ---- Responsive ---- */

@media (max-width: 900px) {
  :root {
    --section-y: var(--section-y-tight);
  }

  .hero {
    grid-template-columns: 1fr;
    gap: 2.75rem;
    padding-top: 3rem;
    padding-bottom: var(--section-y-tight);
  }

  .hero h1 {
    max-width: 100%;
  }

  .hero-art {
    order: -1;
    justify-content: flex-start;
  }

  .hero-art svg {
    max-width: 190px;
  }

  .build-row {
    grid-template-columns: 1fr;
    gap: 0.75rem;
  }

  .product,
  .product-flip {
    grid-template-columns: 1fr;
    gap: 2rem;
  }

  /* Media above copy on every row once stacked, so the two rows read the same
     way on a phone rather than one of them inverting for no reason. */
  .product-media,
  .product-flip .product-media {
    order: -1;
  }
}

@media (max-width: 560px) {
  .container {
    padding-left: 1.25rem;
    padding-right: 1.25rem;
  }

  .site-header .container {
    gap: 1rem;
  }

  .site-nav {
    gap: 1.1rem;
  }

  .wordmark span {
    font-size: 0.95rem;
  }

  .hero-actions .btn {
    flex: 1 1 auto;
  }

  .site-footer .container {
    flex-direction: column;
    align-items: flex-start;
  }

  .footer-links {
    margin-left: 0;
  }
}
