/* XTT / xtt.com
   Black and white, with one tint of black for secondary text.
   Inter Regular for text, Medium for the statement and labels.

   The layout is measured from the mark. The plate is the mark plus its H/2
   clearspace on every side, and nothing else may enter it. Text aligns to the
   mark's own left and right edges. Nothing on the page draws a rule. */

@font-face {
  font-family: "InterVariable";
  src: url("/assets/fonts/InterVariable-subset.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}

:root {
  --ink: #000;
  --paper: #fff;
  --ink-2: #6b6b6b;   /* secondary text, 5.3:1 on white */

  /* Mark proportions from XTT_Master.svg: 1094.2179 x 276.5551.
     The mark is as wide as it can be while the plate (W + H wide, 2H tall)
     fits the page width, leaves --chrome of height for the text, and stays
     under a cap. cqw is the page width, so a scrollbar never pushes the plate
     out. */
  --ratio: 3.956599;
  --chrome: 240px;
  --vh: 1vh;
  --mark-w: max(120px, min(100cqw / 1.252742, (100 * var(--vh) - var(--chrome)) * 1.978300, 1400px));
  --mark-h: calc(var(--mark-w) / var(--ratio));
  --clear: calc(var(--mark-h) / 2);
  --inset: calc((100cqw - var(--mark-w)) / 2);
  --pad: clamp(20px, 4.5vh, 48px);

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  color-scheme: light;
}

/* Small viewport units keep the plate clear of mobile browser chrome. */
@supports (height: 1svh) {
  :root { --vh: 1svh; }
}

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: InterVariable, Inter, Arial, sans-serif;
  font-optical-sizing: auto;
  font-feature-settings: "liga" 1, "calt" 1;
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.28em;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  transition: text-decoration-color 200ms ease;
}
a:hover { text-decoration-color: currentColor; }
a:focus-visible { outline: 1px solid currentColor; outline-offset: 4px; }

/* Frame */

.page {
  container-type: inline-size;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

.top,
.foot {
  display: flex;
  justify-content: space-between;
  gap: 16px 48px;
  padding-inline: var(--inset);
}

/* Statement */

.top {
  align-items: baseline;
  padding-top: var(--pad);
}

.statement {
  margin: 0;
  max-width: 25em;
  font-size: clamp(1.0625rem, 0.95rem + 0.3vw, 1.25rem);
  font-weight: 500;
  line-height: 1.3;
  text-wrap: pretty;
}
.statement span { color: var(--ink-2); }

.contact {
  flex: none;
  font-size: 15px;
  font-weight: 500;
}

/* Plate: the mark and its clearspace. site.js adds the outline and the
   corner squares inside the SVG, plots them, then fills the mark. */

.stage {
  display: grid;
  place-items: center;
}

.plate {
  position: relative;
  display: block;
  margin: 0;
  width: calc(var(--mark-w) + var(--mark-h));
  height: calc(var(--mark-h) * 2);
  font-size: 0;
  -webkit-tap-highlight-color: transparent;
}

.plate svg {
  position: absolute;
  display: block;
  left: var(--clear);
  top: var(--clear);
  width: var(--mark-w);
  height: var(--mark-h);
  overflow: visible;
  color: var(--ink);
}

/* With JavaScript the SVG waits for site.js. If it never runs, the mark
   fades in on its own. */
.js .plate svg { animation: fade 500ms ease 900ms both; }
.plate.is-plotting svg { animation: none; }

/* site.js sets the stroke widths in viewBox units, for 1 CSS px. */
.plate .line {
  fill: none;
  stroke: currentColor;
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
  transition: opacity 400ms ease;
}
.plate .nodes rect {
  fill: var(--paper);
  stroke: currentColor;
  shape-rendering: crispEdges;
  opacity: 0;
  transition: opacity 250ms ease;
}
.plate .nodes rect.on { opacity: 1; }

/* Plotting: outline only. Built: the fill. Open: the construction again. */
.plate.is-plotting .mark { opacity: 0; transition: opacity 600ms ease; }
.plate.is-built .mark { opacity: 1; }
.plate.is-built .line { opacity: 0; }
.plate.is-built.is-open .mark { opacity: 0; }
.plate.is-built.is-open .line { opacity: 1; }

/* The crosshair, in place of the cursor, from site.js. */
.hair {
  position: fixed;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 150ms ease;
}
.hair line {
  stroke: var(--ink);
  stroke-opacity: 0.14;
  stroke-width: 1;
  shape-rendering: crispEdges;
}
.aim, .aim body { cursor: none; }
.aim a { cursor: pointer; }
.aim .hair { opacity: 1; }

/* Footer */

.foot {
  padding-bottom: var(--pad);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink-2);
}

/* Entrance: the mark resolves (site.js), then the words arrive. */

@media (prefers-reduced-motion: no-preference) {
  .top > *,
  .foot {
    animation: rise 1000ms var(--ease-out) 700ms both;
  }
  .contact { animation-delay: 800ms; }
  .foot { animation-name: fade; animation-delay: 950ms; }
}

@media (prefers-reduced-motion: reduce) {
  .js .plate svg { animation: none; }
}

@keyframes fade { from { opacity: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(8px); } }

/* Portrait: the mark drops to the foot of the page, under the words. */

@media (max-aspect-ratio: 4/5) {
  .stage { align-items: end; }
}

@media (max-width: 760px) {
  :root { --chrome: 320px; }
  .top { flex-direction: column; align-items: flex-start; gap: 20px; }
  .contact { font-size: 1rem; }
}

@media print {
  .plate svg, .plate .mark { opacity: 1 !important; animation: none !important; }
  .plate .line, .plate .nodes, .hair { display: none; }
  .page { min-height: 0; }
}
