/* Invisible Investor: one printed sheet, one ink, on black.
   Built to his 1-bit poster (art/ref/poster.jpg), measured in art/ref/measurements.txt:
   ground #000 over 81.54% of his frame, one ink at #e4e2c9 over 12.77%, ink column 92.26% of the
   width, a heavy chamfered grotesk in caps for the loud lines and a plain grotesque for the words.
   Nothing here is a card: the frames are generated 1-bit rasters, nine sliced.

   ONE BLOCK. Every raster on this site is drawn on the grid of his jacket (art/ref/suit.jpg) and
   printed at TWO CSS pixels a block, so the near figure, the crowd behind it, the frames, the
   panel pictures and the marks all use the same pixel. A raster is never shown at a fraction of
   its file size: where a width cannot hold 1056 px the picture is a second file, not a scale.

   ONE TYPE SCALE: 16 / 20 / 24 / 32 / 48 / 72. His list starts at 12, and the kit's floor is 16
   (tools/shots.mjs fails any text under it), so the sheet uses the six steps at and above the
   floor and nothing between them.

   ONE SPACING SCALE: 4 / 8 / 12 / 16 / 24 / 32 / 48, as --s1 to --s7. */

@font-face {
  font-family: "Technor";
  src: url("/assets/fonts/technor-black.woff2") format("woff2");
  font-weight: 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Barlow";
  src: url("/assets/fonts/barlow-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Barlow";
  src: url("/assets/fonts/barlow-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Barlow";
  src: url("/assets/fonts/barlow-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/assets/fonts/jetbrains-mono-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}

:root {
  --ground: #090807;
  --ink: #edE7CE;        /* 16.0 : 1 on the ground */
  --ink-2: #a39d86;      /*  7.3 : 1, secondary words */
  --ink-3: #8e8873;      /*  5.6 : 1, labels, captions, empty states, disabled keys */
  --rule: #6e6a5a;       /*  3.7 : 1, hairlines and separators only, never a word */

  --page: 1128px;        /* the ink column; the plate inside it is 1056, which is 2 x 528 blocks */
  --gutter: 32px;

  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px;

  --display: "Technor", "Arial Black", system-ui, sans-serif;
  --text: "Barlow", system-ui, -apple-system, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "Consolas", monospace;

  --frame-plate: url("/assets/img/frame-plate-128.png");
  --frame-panel: url("/assets/img/frame-panel-72.png");
}

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 400 16px/1.6 var(--text);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; image-rendering: pixelated; }

a { color: var(--ink); }

:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }

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

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--ink); color: var(--ground);
  padding: var(--s3) var(--s5); font: 600 16px/1 var(--text); letter-spacing: .08em; text-transform: uppercase;
}
.skip:focus { left: var(--s5); top: var(--s5); z-index: 20; }

/* ---------------------------------------------------------------- the sheet */

.sheet {
  max-width: calc(var(--page) + var(--gutter) * 2);
  margin: 0 auto;
  padding: var(--s7) var(--gutter);
}

/* --------------------------------------------------------------- the masthead

   The two corners are one shape: a rule across the whole column, then the list under it. The rule
   comes FIRST in the markup, so a four item menu and a three item list still start on the same
   line, and it runs the full width of its own column, so the two are never two lengths. */

.masthead {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr) 240px;
  align-items: start;
  column-gap: var(--s6);
}

.corner { font: 600 16px/1.75 var(--text); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.corner ul { list-style: none; margin: 0; padding: 0; }
.corner .edge { display: block; width: 100%; height: 2px; background: var(--rule); margin: 0 0 var(--s3); }
.corner-r { text-align: right; }

.nav-item { display: block; position: relative; padding-left: 26px; color: var(--ink-3); text-decoration: none; }
.nav-item:hover { color: var(--ink); }
.nav-item[aria-current="page"] { color: var(--ink); }
.nav-item[aria-current="page"]::before {
  content: ""; position: absolute; left: 0; top: 50%; margin-top: -9px;
  width: 18px; height: 18px;
  background: url("/assets/img/mark-star-18.png") no-repeat center / 18px 18px;
}

.mast-centre { text-align: center; }

/* the mark and the two rules beside it: the same 2 px rule the corners use */
.mast-mark { display: flex; align-items: center; justify-content: center; gap: var(--s5); margin: 0; }
.mast-mark::before, .mast-mark::after { content: ""; flex: 1 1 0; height: 2px; background: var(--rule); max-width: 180px; }
.mast-mark img { width: 64px; height: auto; }

.wordmark {
  margin: var(--s4) 0 0;
  font: 900 32px/1 var(--display);
  letter-spacing: .12em;
  text-transform: uppercase;
  display: flex; align-items: center; justify-content: center; gap: 20px;
}
.wordmark img { width: 18px; height: 18px; flex: none; }
.wordmark span { margin-right: -.12em; }

.tagline {
  margin: var(--s3) 0 0;
  font: 500 16px/1 var(--text);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.tagline span { margin-right: -.22em; display: inline-block; }

/* -------------------------------------------------------- headline and lead */

.headline {
  margin: var(--s7) 0 0;
  font: 900 clamp(32px, 7.6vw, 72px)/0.94 var(--display);
  letter-spacing: -.004em;
  text-transform: uppercase;
  text-align: center;
}

.lead {
  margin: var(--s6) auto 0;
  max-width: 78%;
  text-align: center;
  color: var(--ink-2);
  font-size: 20px;
}

.ornament {
  display: flex; align-items: center; justify-content: center; gap: var(--s4);
  margin: var(--s5) 0 0;
  color: var(--ink-3);
  font: 400 16px/1.4 var(--text);
}
.ornament::before, .ornament::after { content: ""; flex: 1 1 0; height: 2px; background: var(--rule); }
.ornament img { width: 18px; height: 18px; flex: none; }
.ornament span { flex: 0 1 auto; min-width: 0; max-width: 68ch; text-align: center; }

/* ------------------------------------------------------------- the frames

   One corner language, two weights: a generated 1-bit rule whose corner steps inwards and leaves a
   single block standing. The plate carries it at 20 px and the panel at 12, and nothing on the
   sheet is a plain CSS box. The inner padding is measured from the rule, never from the text. */

.plate {
  margin-top: var(--s6);
  border: 20px solid transparent;
  border-image: var(--frame-plate) 20 / 20px / 0 stretch;
  padding: var(--s5) var(--s4);
}

.panel {
  border: 12px solid transparent;
  border-image: var(--frame-panel) 12 / 12px / 0 stretch;
  padding: var(--s5) var(--s4);
  display: flex; flex-direction: column;
}

/* --------------------------------------------------- one head for every box */

.plate-title, .panel-head {
  display: flex; align-items: center; gap: var(--s3);
  margin: 0 0 var(--s5);
  padding: 0 .12em var(--s3) 0;
  border-bottom: 2px solid var(--rule);
  color: var(--ink);
  font: 600 20px/1.3 var(--text);
  letter-spacing: .12em;
  text-transform: uppercase;
}
.plate-title img, .panel-head img { width: 32px; height: 32px; flex: none; }
.plate-title span, .panel-head span { margin-right: -.12em; }

/* ---------------------------------------------------------- the day's plate

   The scene is ONE picture: the plain, the crowd and his jacket are composited into the raster by
   tools/art.mjs, never stacked in CSS. Nothing is positioned over anything, so nothing can leave
   the frame, and a width that cannot hold the big drawing is given a smaller DRAWING, never a
   smaller scale: each file prints at one CSS pixel per block of his own grid.
   Only the width is ever set; the height is the file's own. */

.field, .alone { margin: 0; }
.field img, .alone img { display: none; height: auto; margin: 0 auto; }
.field img.wide { display: block; width: 1056px; }
.alone img.wide { display: block; width: 496px; }

.hr { height: 2px; background: var(--rule); border: 0; margin: var(--s5) 0; }

/* The day, as one strip of labelled columns. Every value is set in the same mono at the same
   weight: the countdown is larger because it is the one thing that changes while you watch, and
   that is the whole hierarchy. A number nobody has yet is not a small value, it is a blank: it
   prints the words in the text face over a short rule, so an empty day can never be misread. */
.day {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  column-gap: var(--s6);
  align-items: start;
}
.day > div { min-width: 0; }
.day dt, .label {
  margin: 0;
  font: 600 16px/1.2 var(--text);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.day dd { margin: var(--s3) 0 0; font: 500 24px/1.1 var(--mono); font-variant-numeric: tabular-nums; }
.day .lead-value { font-size: 48px; line-height: 1; letter-spacing: -.02em; }
.day dd.empty {
  color: var(--ink-3);
  font: 600 20px/1.2 var(--text);
  letter-spacing: .1em;
  text-transform: uppercase;
}
.day dd.empty::after { content: ""; display: block; width: 56px; height: 2px; background: var(--rule); margin-top: var(--s2); }

.act { display: flex; gap: var(--s4); align-items: center; margin-top: var(--s6); }
.act .key { flex: none; }
.act .note { align-self: center; color: var(--ink-3); font-size: 16px; margin: 0; }

/* ------------------------------------------------------------ the mint plate

   The ticker, the field and the key are one row of one height: three boxes of three heights on one
   line is the thing that reads as a form that was never finished. */

.mint-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--s4);
  align-items: stretch;
}
.mint-ticker {
  display: flex; align-items: center;
  min-height: 56px;
  font: 900 24px/1 var(--display); letter-spacing: .04em;
}
.mint {
  display: flex; align-items: center;
  min-height: 56px;
  font: 500 clamp(16px, 1.8vw, 24px)/1.4 var(--mono);
  color: var(--ink);
  background: transparent;
  border: 0;
  padding: var(--s3) var(--s4);
  box-shadow: inset 0 0 0 2px var(--rule);
  overflow-wrap: anywhere;
  min-width: 0;
  user-select: all;
}
.mint.empty { color: var(--ink-3); user-select: auto; letter-spacing: .06em; }
.mint-row .key { min-height: 56px; }

.copystate { margin: var(--s3) 0 0; color: var(--ink-3); font-size: 16px; min-height: 1.6em; }

.keys { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s4); margin-top: var(--s5); }

/* ---------------------------------------------------------------- the keys

   No key on the sheet carries a mark. pump.fun answers 403 to every request for its own icon, and
   a row where three keys wear a mark and one does not reads as a row that failed to load, so the
   four carry the platform's name as text and nothing else. */

.key {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 56px;
  padding: 0 24px;
  border: 2px solid var(--ink);
  background: transparent;
  color: var(--ink);
  font: 600 16px/1 var(--text);
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  cursor: pointer;
  transition: background .12s linear, color .12s linear, transform .08s linear;
}
.key > span { margin-right: -.1em; }
.key:hover { background: var(--ink); color: var(--ground); }
.key:active { transform: translateY(1px); }
.key.primary { background: var(--ink); color: var(--ground); }
.key.primary:hover { background: var(--ink-2); }
/* A disabled key is still a word a reader has to read: it keeps the muted ink at 5.6:1 and is
   never faded on top of that, which is what drops a key to about 3:1 without anyone measuring. */
.key[aria-disabled="true"], .key:disabled {
  border-color: var(--rule); color: var(--ink-3); cursor: default;
}
.key[aria-disabled="true"]:hover, .key:disabled:hover { background: transparent; color: var(--ink-3); }
.key.primary:disabled, .key.primary[aria-disabled="true"] { background: transparent; }
.key.wide { width: 100%; }

/* --------------------------------------------------------------- the panels */

.panels {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s5);
  margin-top: var(--s6);
  align-items: stretch;
}

.panel figure { margin: 0; }
.panel figure img { width: 224px; height: auto; margin: 0 auto; }

.captions {
  display: grid; grid-template-columns: repeat(3, 1fr);
  width: 224px; max-width: 100%;
  margin: var(--s4) auto 0;
  min-height: 2.8em;             /* two lines reserved, so all three panels keep one baseline */
  align-content: start;
  text-align: center;
}
.captions span { font: 600 16px/1.4 var(--text); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }

.panel p { margin: var(--s4) 0 0; font-size: 16px; color: var(--ink-2); }
.panel p:last-child { margin-bottom: 0; }
/* .panel p would otherwise win on specificity and take the auto margins off the caption row */
.panel .captions { margin: var(--s4) auto 0; }

/* ------------------------------------------- the check page's two columns */

.split { display: grid; grid-template-columns: 496px minmax(0, 1fr); gap: var(--s6); align-items: start; }

/* ----------------------------------------------------------------- the note */

.note-plate .cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s6); }
.note-plate p { margin: 0 0 var(--s4); color: var(--ink-2); font-size: 16px; }
.note-plate p:last-child { margin-bottom: 0; }
.note-plate strong { color: var(--ink); font-weight: 600; }

/* -------------------------------------------------------- shared text blocks */

.page-title {
  margin: var(--s7) 0 0;
  font: 900 clamp(32px, 4.4vw, 48px)/1 var(--display);
  letter-spacing: -.004em;
  text-transform: uppercase;
  text-align: center;
}

.rows { margin: 0; }
.rows > div {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s4);
  align-items: baseline;
  padding: var(--s3) 0;
  border-bottom: 2px solid var(--rule);
}
.rows > div:last-child { border-bottom: 0; }
.rows dt { font: 600 16px/1.3 var(--text); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); margin: 0; }
select { max-width: 100%; }
.rows dd { margin: 0; font: 500 20px/1.3 var(--mono); font-variant-numeric: tabular-nums; text-align: right; overflow-wrap: anywhere; }
.rows dd.empty {
  color: var(--ink-3);
  font: 600 16px/1.3 var(--text);
  letter-spacing: .1em;
  text-transform: uppercase;
}

.field-label { display: block; font: 600 16px/1.3 var(--text); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-bottom: var(--s3); }

input[type="text"] {
  width: 100%;
  min-height: 56px;
  padding: var(--s3) var(--s4);
  background: transparent;
  border: 2px solid var(--rule);
  color: var(--ink);
  font: 500 16px/1.4 var(--mono);
}
input[type="text"]:focus { border-color: var(--ink); outline: none; }
input[type="text"]::placeholder { color: var(--ink-3); }
/* never faded: an opacity on top of the muted ink is what takes a disabled field under 4.5 : 1 */
input[type="text"]:disabled { border-color: var(--rule); color: var(--ink-3); }

.state { margin: var(--s5) 0 0; font-size: 16px; color: var(--ink-2); min-height: 1.6em; }
.state.good { color: var(--ink); }
.state.bad { color: var(--ink); }

table { width: 100%; border-collapse: collapse; }
caption { text-align: left; font: 600 16px/1.3 var(--text); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); padding: 0 0 var(--s3); }
th, td { text-align: left; padding: var(--s3) var(--s4); border-bottom: 2px solid var(--rule); font-size: 16px; }
th:first-child, td:first-child { padding-left: 0; }
th:last-child, td:last-child { padding-right: 0; }
th { font: 600 16px/1.3 var(--text); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
td.num, th.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
td.hash { font-family: var(--mono); overflow-wrap: anywhere; }
tbody tr:last-child td { border-bottom: 0; }
/* a labelled sample, printed in the muted ink so it can never be read as a real day */
table.sample tbody td { color: var(--ink-3); }

.empty-state { color: var(--ink-3); font-size: 16px; margin: var(--s5) 0 0; }

/* ------------------------------------------------- small shared text blocks */

.note { margin: var(--s3) 0 0; color: var(--ink-3); font-size: 16px; }
.stack { margin-top: var(--s5); }
.picker { margin: 0 0 var(--s5); }
.rows-top { margin-bottom: var(--s5); }

.check-row { display: flex; align-items: center; gap: var(--s3); margin: var(--s4) 0 0; }
.check-row input { width: 22px; height: 22px; accent-color: #edE7CE; flex: none; }
.check-row label { font-size: 16px; color: var(--ink-2); }

select {
  min-height: 56px;
  padding: 0 var(--s4);
  background: transparent;
  border: 2px solid var(--rule);
  color: var(--ink);
  font: 500 16px/1.4 var(--mono);
}

/* --------------------------------------------------------------- the widths

   The scene changes FILE, never scale: at 1192 px the column holds 1056, under it the same drawing
   is printed at one CSS pixel a block, and a phone gets its own plain. His jacket follows, each
   time at a whole scale of his own grid. */

@media (max-width: 1191px) {
  :root { --page: 100%; }
  .split { grid-template-columns: minmax(0, 1fr); }
  .day { grid-template-columns: 1fr 1fr; row-gap: var(--s5); }

  /* the column no longer holds 1056, so the masthead gives the wordmark room instead of letting
     it break in two with a star hanging beside each line */
  .masthead { grid-template-columns: 190px minmax(0, 1fr) 190px; }
  .wordmark { font-size: 24px; }

  .field img.wide { display: none; }
  .field img.mid { display: block; width: 496px; }
}

@media (min-width: 880px) and (max-width: 1191px) {
  #today { display: grid; grid-template-columns: 496px minmax(0, 1fr); column-gap: var(--s6); align-items: start; }
  #today .field { grid-column: 1; grid-row: 1 / span 2; }
  #today .hr { display: none; }
  #today .day { grid-column: 2; grid-row: 1; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
  #today .act { grid-column: 2; grid-row: 2; margin-top: var(--s5); flex-direction: column; align-items: stretch; }
  #today .act .note { align-self: stretch; }
}

@media (max-width: 1087px) {
  /* three panels of 260 px of picture each stop fitting across: they go down the sheet */
  .panels { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 860px) {
  .masthead { grid-template-columns: minmax(0, 1fr); row-gap: var(--s5); justify-items: stretch; }
  .mast-centre { order: -1; }
  .corner, .corner-r { text-align: center; }
  .corner-l ul { display: grid; grid-template-columns: repeat(2, auto); column-gap: var(--s6); justify-content: center; }
  .nav-item { padding-left: 24px; text-align: left; }
  .lead { max-width: 100%; }
  .note-plate .cols { grid-template-columns: minmax(0, 1fr); gap: var(--s4); }
  .keys { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* the two rules beside the line shrink to a stub once the sentence fills the width, and a 14 px
     dash at the edge of the sheet is debris, not a rule: below this they go */
  .ornament::before, .ornament::after { display: none; }

  /* the run stacks: four columns of hashes cannot hold a phone's width, so each day becomes a
     block and every cell prints its own column name */
  table, tbody, tr, td { display: block; width: 100%; }
  thead { position: absolute; left: -9999px; }
  tbody tr { border-bottom: 2px solid var(--rule); padding: var(--s4) 0; }
  tbody tr:last-child { border-bottom: 0; }
  td, td.num { border: 0; padding: var(--s1) 0; text-align: left; }
  td::before {
    content: attr(data-label);
    display: block;
    font: 600 16px/1.6 var(--text); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
  }
}

@media (max-width: 655px) {
  :root { --gutter: 20px; }
  .sheet { padding-top: var(--s6); }
  .day { grid-template-columns: minmax(0, 1fr); }
  .day .lead-value { font-size: 32px; }
  .mint-row { grid-template-columns: minmax(0, 1fr); }
  .mint-ticker { font-size: 24px; min-height: 0; }
  .act { flex-direction: column; align-items: stretch; }
  .act .key { width: 100%; }
  .act .note { align-self: stretch; }
  .ornament::before, .ornament::after { display: none; }
  .plate { border-width: 14px; border-image-width: 14px; padding: var(--s5) var(--s4); }
  .panel { border-width: 8px; border-image-width: 8px; }
  .key { padding: 0 16px; }
  /* four keys of one width, stacked: at this width two columns clip the longest platform name */
  .keys { grid-template-columns: minmax(0, 1fr); }
  /* a label and its value stop sharing a line: at this width the label is squeezed to nothing */
  .rows > div { grid-template-columns: minmax(0, 1fr); row-gap: var(--s1); }
  .rows dd { text-align: left; }
  select { width: 100%; max-width: 100%; }

  .field img.mid, .alone img.wide { display: none; }
  .field img.narrow, .alone img.narrow { display: block; width: 208px; }
}

@media (max-width: 359px) {
  .wordmark { font-size: 24px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
