/**
 * tilas.xyz — the whole stylesheet.
 *
 * Paper and ink. Every rule on the page is a one-pixel line of ink, every label is the mono face
 * set small in capitals, every headline is the sans set as large as the column allows, and the
 * one thing that is not paper — the live app in the hero, the pipeline strip, a button — is a
 * block of ink. Nothing is round and nothing casts a shadow: the page is a printed sheet, not a
 * stack of cards, and the app it embeds is the darkest object on it by design.
 *
 * Every non-colour value here is a `var(--…)` out of `packages/ui/src/tokens.css`, which
 * `build.tsx` emits beside this file: the type sizes, the three weights, the two trackings, the
 * 4px spacing base, the motion tokens and the fonts. Display sizes are `clamp()`s over those
 * sizes and the viewport — a relationship, not a fifth size. Colour is the one layer the site
 * owns, in `palette.css`, which redefines the same semantic names this file has always used;
 * `tokenSources.test.ts` still covers this directory, so a hex here fails the build, and
 * `palette.test.ts` refuses a radius or a shadow.
 *
 * Hand-written rather than Tailwind because a marketing page is a document. It ships no
 * JavaScript at all: `build.tsx` renders React to static HTML once, and nothing is hydrated, and
 * nothing on it moves — the only motion is a colour swapping under a pointer.
 */

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

html {
  color-scheme: light;
}

body {
  margin: 0;
  background: var(--surface-0);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--text-panel);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--text-primary);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

a:hover {
  background: var(--accent);
  color: var(--accent-contrast);
  text-decoration: none;
}

:focus-visible {
  outline: 2px solid var(--border-strong);
  outline-offset: 2px;
}

h1,
h2,
h3 {
  font-weight: var(--font-weight-semibold);
  margin: 0;
  text-wrap: balance;
}

/* Display sizes: fluid between two multiples of the title token, so the sheet reads as a poster
   at desk width and as a page on a phone without a breakpoint deciding where. */
h1 {
  font-size: clamp(calc(var(--text-title) * 2.4), 8vw, calc(var(--text-title) * 5.5));
  line-height: 0.95;
}

h2 {
  font-size: clamp(calc(var(--text-title) * 1.5), 4vw, calc(var(--text-title) * 2.8));
  line-height: 1.05;
}

h3 {
  font-size: var(--text-title);
  line-height: 1.2;
}

p {
  margin: 0;
  max-width: 64ch;
}

/* --- the mono voice ---------------------------------------------------------------------- */

/* Captions, nav, figures, the pipeline: everything that is a reading rather than a sentence. */
.label {
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: var(--text-ui);
  letter-spacing: var(--tracking-label);
  line-height: 1.4;
  text-transform: uppercase;
}

.label strong {
  color: var(--text-primary);
  font-weight: var(--font-weight-normal);
}

/* --- frame ------------------------------------------------------------------------------- */

.wrap {
  margin: 0 auto;
  max-width: calc(var(--spacing) * 340);
  padding: 0 calc(var(--spacing) * 6);
}

/* A full-bleed band: the rule runs edge to edge, the content sits inside the frame. */
.band {
  border-top: 1px solid var(--border-strong);
}

.nav {
  background: var(--surface-0);
  border-bottom: 1px solid var(--border-strong);
  font-family: var(--font-mono);
  font-size: var(--text-ui);
  letter-spacing: var(--tracking-label);
  position: sticky;
  text-transform: uppercase;
  top: 0;
  z-index: 1;
}

.nav-inner {
  align-items: center;
  display: flex;
  gap: calc(var(--spacing) * 6);
  /* The app's own bar height, so the two products' chrome measures the same. */
  height: var(--spacing-topbar);
}

.nav a {
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  padding: calc(var(--spacing) * 1) 0;
  text-decoration: none;
}

.nav a:hover {
  background: transparent;
  border-bottom-color: var(--border-strong);
  color: var(--text-primary);
}

.nav a[aria-current="page"] {
  border-bottom-color: var(--border-strong);
  color: var(--text-primary);
}

.wordmark,
.nav a.wordmark {
  align-items: center;
  border-bottom: 0;
  color: var(--text-primary);
  display: inline-flex;
  font-weight: var(--font-weight-semibold);
  gap: calc(var(--spacing) * 3);
  letter-spacing: var(--tracking-wordmark);
  margin-right: auto;
}

/* The mark carries its own dark ground; on paper it is a tile of ink, which is the point. */
.mark {
  display: block;
}

section {
  padding: calc(var(--spacing) * 20) 0;
}

/* The seven pages that still write plain sections inside the frame keep an ink rule between
   them; the homepage draws its own full-bleed bands instead. */
.page section {
  border-top: 1px solid var(--border-strong);
}

.page section:first-of-type {
  border-top: 0;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: calc(var(--spacing) * 5);
}

.lede {
  font-size: var(--text-title);
  line-height: 1.35;
}

.small {
  color: var(--text-muted);
  font-size: var(--text-ui);
  line-height: 1.55;
}

/* --- footer ------------------------------------------------------------------------------ */

footer {
  border-top: 1px solid var(--border-strong);
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: var(--text-ui);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.footer-inner {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.footer-inner > * {
  border-left: 1px solid var(--border-subtle);
  padding: calc(var(--spacing) * 8) calc(var(--spacing) * 4);
}

.footer-inner > :first-child {
  border-left: 0;
  padding-left: 0;
}

footer a {
  color: var(--text-muted);
  text-decoration: none;
}

footer a:hover {
  color: var(--accent-contrast);
}

/* --- the grid ---------------------------------------------------------------------------- */

/* Twelve columns with the gutters drawn: a cell is separated from the one before it by a
   hairline, and a row from the one above by the ink rule. Column spans are set per section. */
.cols {
  display: grid;
  gap: 0;
  grid-template-columns: repeat(12, minmax(0, 1fr));
}

.cols > * {
  border-left: 1px solid var(--border-subtle);
  min-width: 0;
  padding: calc(var(--spacing) * 5) calc(var(--spacing) * 5) calc(var(--spacing) * 5)
    calc(var(--spacing) * 4);
}

.cols > :first-child,
.cols > .row-start {
  border-left: 0;
  padding-left: 0;
}

.span-4 {
  grid-column: span 4;
}

.span-5 {
  grid-column: span 5;
}

.span-6 {
  grid-column: span 6;
}

.span-7 {
  grid-column: span 7;
}

.span-8 {
  grid-column: span 8;
}

.span-10 {
  grid-column: span 10;
}

.span-12 {
  grid-column: span 12;
}

.from-8 {
  grid-column: 8 / span 5;
}

/* A ruled ledger: equal columns, a hairline between cells, the ink rule above and below, and a
   hairline between rows when there is more than one. Three columns unless told otherwise. */
.ledger {
  border-bottom: 1px solid var(--border-strong);
  border-top: 1px solid var(--border-strong);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.ledger > * {
  border-left: 1px solid var(--border-subtle);
  display: flex;
  flex-direction: column;
  gap: calc(var(--spacing) * 3);
  min-width: 0;
  padding: calc(var(--spacing) * 6) calc(var(--spacing) * 5);
}

.ledger > :nth-child(3n + 1) {
  border-left: 0;
  padding-left: 0;
}

.ledger > :nth-child(n + 4) {
  border-top: 1px solid var(--border-subtle);
}

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

.ledger-4 > :nth-child(3n + 1) {
  border-left: 1px solid var(--border-subtle);
  padding-left: calc(var(--spacing) * 5);
}

.ledger-4 > :nth-child(4n + 1) {
  border-left: 0;
  padding-left: 0;
}

.ledger-4 > :nth-child(n + 4) {
  border-top: 0;
}

.ledger-4 > :nth-child(n + 5) {
  border-top: 1px solid var(--border-subtle);
}

/* A tool's cell: its group and name as the caption, what it does as the heading. */
.tools h3 {
  margin-top: calc(var(--spacing) * 2);
}

/* --- controls ---------------------------------------------------------------------------- */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--spacing) * 3);
}

/* An ink block; hovering or focusing it turns it the accent. `.button-primary` is the same
   thing under the name the other pages already use. */
.button,
.button-primary {
  background: var(--surface-3);
  border: 1px solid var(--border-strong);
  color: var(--surface-0);
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-ui);
  letter-spacing: var(--tracking-label);
  line-height: 1;
  padding: calc(var(--spacing) * 4) calc(var(--spacing) * 5);
  text-decoration: none;
  text-transform: uppercase;
  transition:
    background-color var(--default-transition-duration) var(--ease-out),
    color var(--default-transition-duration) var(--ease-out);
}

.button:hover,
.button:focus-visible,
.button-primary:hover,
.button-primary:focus-visible {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

/* Paper with an ink border; it inverts to ink rather than to the accent, so the page has one
   orange thing at a time. */
.button-outline {
  background: var(--surface-0);
  color: var(--text-primary);
}

.button-outline:hover,
.button-outline:focus-visible {
  background: var(--surface-3);
  border-color: var(--border-strong);
  color: var(--surface-0);
}

/* --- content ----------------------------------------------------------------------------- */

.grid {
  border-top: 1px solid var(--border-strong);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(var(--spacing) * 64), 1fr));
}

.grid > * {
  border-bottom: 1px solid var(--border-strong);
  border-left: 1px solid var(--border-subtle);
}

.grid > :first-child {
  border-left: 0;
}

.card {
  background: var(--surface-1);
  padding: calc(var(--spacing) * 5);
}

table {
  border-collapse: collapse;
  border-top: 1px solid var(--border-strong);
  width: 100%;
}

th {
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: var(--text-ui);
  font-weight: var(--font-weight-normal);
  letter-spacing: var(--tracking-label);
  text-align: left;
  text-transform: uppercase;
}

th,
td {
  border-bottom: 1px solid var(--border-strong);
  padding: calc(var(--spacing) * 3) calc(var(--spacing) * 4) calc(var(--spacing) * 3) 0;
  vertical-align: top;
}

td {
  font-variant-numeric: tabular-nums;
}

/* The product's column on a spec sheet: a block of the accent with the name set in ink. */
th.ours {
  background: var(--accent);
  color: var(--accent-contrast);
  padding-left: calc(var(--spacing) * 3);
}

.scroll {
  overflow-x: auto;
}

.pipeline {
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: var(--text-ui);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.pipeline strong {
  color: var(--text-primary);
  font-weight: var(--font-weight-normal);
}

.figure {
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: var(--text-title);
  font-variant-numeric: tabular-nums;
}

/* A measurement set as large as a headline. Mono, so the digits sit on a grid of their own. */
.figure-display {
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: clamp(calc(var(--text-title) * 1.6), 3.6vw, calc(var(--text-title) * 3));
  font-variant-numeric: tabular-nums;
  line-height: 1;
  white-space: nowrap;
}

/* Status is never colour alone (DESIGN.md §6) — every one of these is a word first. */
.state-shipped {
  color: var(--ok);
}

.state-progress {
  color: var(--warning);
}

.state-planned {
  color: var(--text-muted);
}

/* --- the embedded app -------------------------------------------------------------------- */

/* A ruled caption strip above the frame, then the frame itself with a heavier ink border: the
   darkest object on the page, and the only one that is not paper or type. */
.app-caption {
  border-top: 1px solid var(--border-strong);
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--spacing) * 4);
  justify-content: space-between;
  padding: calc(var(--spacing) * 3) 0;
}

.app-frame {
  aspect-ratio: 16 / 10;
  background: var(--surface-3);
  border: 2px solid var(--border-strong);
  display: block;
  width: 100%;
}

/* --- hero -------------------------------------------------------------------------------- */

.hero {
  padding-bottom: calc(var(--spacing) * 14);
}

.hero h1 {
  margin-top: calc(var(--spacing) * 8);
}

/* --- narrow ------------------------------------------------------------------------------- */

/*
 * The one media query on the site, and it does what DESIGN.md §3 refuses to do in the *app*:
 * reflow. That is not an inconsistency — the app is a desktop-class tool with a 3D viewport and
 * says so, and this is a document. A stranger meeting the product for the first time is often
 * doing it on a phone, and MARKETING.md's whole first guarantee is "it opens".
 *
 * Every ruled grid becomes one column, and the hairline that stood between cells lies between
 * rows instead. The nav stops being a fixed-height bar so its second row has somewhere to go.
 * The display sizes need nothing: the clamp floors are already phone sizes.
 */
@media (max-width: 640px) {
  .nav {
    position: static;
  }

  .nav-inner {
    flex-wrap: wrap;
    gap: calc(var(--spacing) * 4);
    height: auto;
    padding-bottom: calc(var(--spacing) * 3);
    padding-top: calc(var(--spacing) * 3);
  }

  .nav a.wordmark {
    width: 100%;
  }

  section {
    padding: calc(var(--spacing) * 12) 0;
  }

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

  .footer-inner > * {
    border-left: 0;
    border-top: 1px solid var(--border-subtle);
    padding-left: 0;
    padding-right: 0;
  }

  .footer-inner > :first-child {
    border-top: 0;
  }

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

  .cols > *,
  .ledger > *,
  .grid > * {
    border-left: 0;
    border-top: 1px solid var(--border-subtle);
    padding-left: 0;
    padding-right: 0;
  }

  .ledger > :nth-child(n + 1),
  .ledger-4 > :nth-child(n + 1) {
    border-left: 0;
    border-top: 1px solid var(--border-subtle);
    padding-left: 0;
  }

  .cols > :first-child,
  .ledger > :first-child,
  .ledger-4 > :first-child,
  .grid > :first-child {
    border-top: 0;
  }

  .span-4,
  .span-5,
  .span-6,
  .span-7,
  .span-8,
  .span-10,
  .span-12,
  .from-8 {
    grid-column: auto;
  }
}
