/* Solamian Passport. One phosphor CRT browser window standing on a living wall of stamp impressions.
   Built to the picture in art/ref/ref_browser.jpg: its bands, its 62/38 mirrored rows, its flat fills,
   its clustered dot halftones, one monospace family, radius 10 on everything that is pressed. */

@font-face { font-family: Xenon; src: url(/fonts/MonaspaceXenon-Regular.woff2) format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: Xenon; src: url(/fonts/MonaspaceXenon-Medium.woff2) format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: Xenon; src: url(/fonts/MonaspaceXenon-Bold.woff2) format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: Xenon; src: url(/fonts/MonaspaceXenon-BoldItalic.woff2) format("woff2"); font-weight: 700; font-style: italic; font-display: swap; }

:root {
  --void: #000000;
  --ink: #0B110A;
  --shell: #2B3A2A;
  --panel: #364236;
  --panel-2: #2A362A;
  --inset: #141C13;
  --sage: #8AAB8C;
  --sage-hi: #BCD6B8;
  --sage-dim: #93AE92;
  --on-sage: #16210F;
  --text: #DCEBD2;
  --title: #DCF2C8;
  --dim: #BDD2B2;
  --muted: #9FB89C;
  --phos: #EAFFA8;

  /* The passport is printed matter: dark ink on pale paper. The plate's two paper tones are
     #C2D6B2 and #DFEDC8, so the ink is measured against the darker: 11.4:1 and 7.4:1. */
  --paper-ink: #111B0C;
  --paper-dim: #2C3F23;
  --paper-rule: #44603A;

  --t-display: 52px;
  --t-h2: 30px;
  --t-body: 20px;
  --t-label: 18px;
  --t-small: 17px;
  --t-mint: 26px;

  --s1: 8px; --s2: 16px; --s3: 24px; --s4: 32px; --s5: 48px; --s6: 72px;
  --r: 10px;
  --r-win: 14px;
  --key-h: 56px;
  --win-w: 1760px;
  --margin: 32px;

  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { background: var(--ink); }
body {
  min-height: 100vh;
  background: var(--ink);
  color: var(--text);
  font: 500 var(--t-body)/1.55 Xenon, ui-monospace, monospace;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img { display: block; max-width: 100%; }
button, input, a { font: inherit; color: inherit; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---------- the living ground: the wall behind the terminal ---------- */
#ground {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
}
.scan {
  position: fixed; inset: 0; z-index: 90; pointer-events: none;
  background: url(/img/tex/scan.png) repeat;
  opacity: 0.7;
  animation: drift 9s linear infinite;
}
@keyframes drift { from { background-position-y: 0; } to { background-position-y: 6px; } }

/* ---------- the window ---------- */
.win {
  position: relative; z-index: 10;
  width: min(var(--win-w), 100% - var(--margin) * 2);
  margin: var(--margin) auto;
  border-radius: var(--r-win);
  background: var(--shell);
  overflow: hidden;
  box-shadow: 0 0 0 1px #1B2619, 0 24px 90px -20px #000A;
}

/* tab strip: the nav is the browser's own tabs */
.tabs {
  display: flex; align-items: flex-end; gap: var(--s2);
  background: var(--sage);
  background-image: url(/img/tex/grain.png);
  background-blend-mode: soft-light;
  padding: 10px 18px 0;
  min-height: 62px;
}
.tabs__row { display: flex; gap: 6px; flex: 1 1 auto; min-width: 0; flex-wrap: wrap; }
.tab {
  appearance: none; border: 0; cursor: pointer;
  background: var(--panel-2);
  color: var(--sage-hi);
  border-radius: var(--r) var(--r) 0 0;
  height: 52px; padding: 0 26px;
  font-size: var(--t-label); letter-spacing: 0.01em;
  transition: background .12s, color .12s;
}
.tab:hover { background: var(--panel); color: var(--text); }
.tab.is-open { background: var(--shell); color: var(--phos); }
.tab:focus-visible { outline: 3px solid var(--phos); outline-offset: -3px; }

.lamps { display: flex; align-items: center; gap: 10px; padding-bottom: 14px; flex: 0 0 auto; }
.lamp { width: 20px; height: 20px; }
.lamps__say { font-size: var(--t-small); color: var(--on-sage); min-width: 96px; }

/* the frame holds the toolbar and the open view */
.frame { background: var(--shell); }

/* toolbar */
.bar {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px;
  background: var(--shell);
}
.bar__nav, .bar__keys { display: flex; gap: 8px; flex: 0 0 auto; }
.gkey {
  appearance: none; border: 0; cursor: pointer;
  width: 52px; height: 52px; border-radius: var(--r);
  background: transparent;
  display: grid; place-items: center;
  transition: background .12s, opacity .12s;
}
.gkey img { width: 26px; height: 26px; }
.gkey:hover { background: #ffffff14; }
.gkey--dark { background: var(--void); }
.gkey--dark:hover { background: #121912; }
.gkey:disabled { opacity: .45; cursor: default; }
.gkey:focus-visible { outline: 3px solid var(--phos); outline-offset: 2px; }

.field {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 10px;
  background: var(--void);
  border-radius: var(--r);
  padding: 0 10px 0 22px;
  height: 56px;
}
.field__in {
  flex: 1 1 auto; min-width: 0;
  background: transparent; border: 0; outline: none;
  color: var(--phos);
  font-size: var(--t-label); letter-spacing: 0.01em;
  padding: 0;
}
.field__in::placeholder { color: var(--muted); }
.field:focus-within { box-shadow: inset 0 0 0 2px var(--phos); }
.field__go {
  appearance: none; border: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  height: 42px; padding: 0 22px; border-radius: 8px; flex: 0 0 auto;
  background: var(--sage); color: var(--on-sage);
  white-space: nowrap;
  font-size: var(--t-label);
}
.field__go img { width: 22px; height: 22px; filter: brightness(0.25) saturate(0.4); }
.field__go:hover { background: var(--sage-hi); }
.field__go:focus-visible { outline: 3px solid var(--phos); outline-offset: 2px; }

/* The reader's line is the only thing on the page that changes length, so it keeps two lines of
   room at every width: pressing Stamp me must move nothing below it. */
.note {
  margin: 0; padding: 0 18px 10px;
  font-size: var(--t-small); line-height: 1.5; color: var(--dim);
  height: calc(2 * 1.5em + 10px);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ---------- the full bleed band ---------- */
.band { line-height: 0; background: var(--ink); }
.band img { width: 100%; height: clamp(190px, 22vw, 420px); object-fit: cover; object-position: center; }

/* ---------- the sheet of rows ---------- */
.sheet { padding: var(--s2); display: grid; gap: var(--s2); }
.row { display: grid; gap: var(--s2); align-items: stretch; }
.row--a { grid-template-columns: minmax(0, 1.62fr) minmax(0, 1fr); }
.row--b { grid-template-columns: minmax(0, 1fr) minmax(0, 1.62fr); }
.row--steps { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.head { padding: var(--s3) var(--s3) 0; }
.display {
  margin: 0;
  font: italic 700 var(--t-display)/1.08 Xenon, monospace;
  color: var(--title);
  letter-spacing: -0.01em;
}
.display--sm { font-size: var(--t-h2); }
.lede { margin: 14px 0 0; color: var(--text); max-width: 56ch; }

/* ---------- the passport ---------- */
.book { display: flex; flex-direction: column; gap: var(--s2); min-width: 0; justify-content: space-between; }
.book__plate {
  position: relative; flex: 0 0 auto; width: 100%;
  aspect-ratio: 3 / 2;
  border-radius: var(--r); overflow: hidden;
  background: var(--ink);
}
.book__paper { width: 100%; height: 100%; object-fit: fill; }
.book__ink { position: absolute; inset: 0; }
.book__specimen {
  /* centred on the right hand page, clear of the spine; on one page it sits in the middle */
  position: absolute; left: 74%; bottom: 3.2%; transform: translateX(-50%);
  font-size: var(--t-small); letter-spacing: .08em; color: var(--paper-dim);
  text-transform: lowercase;
}
.book.is-read .book__specimen { visibility: hidden; }

/* the photo window, measured off the generated plate */
.photo {
  position: absolute;
  left: 11.17%; top: 12.67%; width: 25.89%; height: 39.91%;
}
/* the five printed lines of the left page, measured off the plate */
.rows { position: absolute; left: 8.67%; top: 54.708%; width: 31.66%; }
.rows__r {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 12px;
  margin: 0; height: 5.875cqh; padding-bottom: 1.5cqh;
  font-size: clamp(16px, 2cqw, 22px);
  color: var(--paper-ink); line-height: 1.15;
}
.rows__r span { color: var(--paper-dim); }
.rows__r b { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.book__plate { container-type: size; }

/* the stamp field on the right page */
.pages { position: absolute; left: 54%; top: 7%; width: 40%; height: 84%; }
.pages__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2%; height: 100%; align-content: start; }
.pages__s { position: relative; aspect-ratio: 1; }
.pages__s img { width: 100%; height: 100%; object-fit: contain; }
.pages__s.is-new { animation: thump .42s cubic-bezier(.2,1.6,.4,1) both; }
@keyframes thump { 0% { transform: scale(2.4) rotate(-9deg); opacity: 0; } 55% { opacity: 1; } 100% { transform: scale(1) rotate(var(--tilt, 0deg)); opacity: 1; } }
.pages__rows { height: 100%; display: grid; align-content: start; gap: 0; }
.pages__row {
  display: flex; justify-content: space-between; gap: 8px;
  font-size: clamp(16px, 1.7cqw, 20px); color: var(--paper-ink); font-weight: 700;
  border-bottom: 1px solid var(--paper-rule); padding: 2.4% 4% 1.3%;
}
.pages__empty { font-size: clamp(16px, 1.6cqw, 20px); color: var(--paper-dim); margin: 0; line-height: 1.5; }

.book__keys { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s1); }

/* ---------- keys ---------- */
.key {
  appearance: none; border: 0; cursor: pointer; text-decoration: none;
  min-height: var(--key-h); padding: 12px 26px;
  border-radius: var(--r);
  background: var(--sage); color: var(--on-sage);
  display: flex; align-items: center; justify-content: center; gap: 12px;
  font-size: var(--t-label); text-align: center;
  transition: background .12s, opacity .12s;
}
.key img { width: 22px; height: 22px; filter: brightness(0.25) saturate(0.4); }
.key:hover { background: var(--sage-hi); }
.key:focus-visible { outline: 3px solid var(--phos); outline-offset: 2px; }
.key.is-on { background: var(--phos); }
.key--wide { width: 100%; }
.key--dark { background: var(--void); color: var(--text); }
.key--dark img { filter: none; }
.key--dark:hover { background: #121912; }
.key:disabled, .key[aria-disabled="true"] { opacity: .58; cursor: default; pointer-events: none; }

/* ---------- the terminal readout column ---------- */
.col { display: flex; flex-direction: column; gap: var(--s3); padding: var(--s3) var(--s3) var(--s2); min-width: 0; justify-content: space-between; }
.read { display: grid; gap: 0; }
.read__r {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s2);
  margin: 0; padding: 14px 20px; min-height: 58px;
  border-bottom: 1px solid #ffffff22;
  font-size: var(--t-label); line-height: 1.5;
}
.read__r span { color: var(--dim); }
.read__r b { color: var(--phos); font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; min-width: 0; overflow-wrap: anywhere; }
.read--big .read__r { padding: 16px 20px; font-size: var(--t-body); }
.read--big .read__r:last-child { border-bottom: 0; }

.ribbon { display: grid; grid-template-columns: repeat(9, minmax(0, 1fr)); gap: 6px; }
.ribbon__s { position: relative; aspect-ratio: 1; border-radius: 8px; background: var(--panel-2); display: grid; place-items: center; }
.ribbon__s img { width: 84%; height: 84%; object-fit: contain; opacity: .38; }
.ribbon__s.is-on img { opacity: 1; }

/* ---------- the fee tile: phosphor lines over the desk ---------- */
.tile { position: relative; border-radius: var(--r); overflow: hidden; background: var(--ink); min-height: 420px; }
.tile__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tile__ink { position: relative; padding: var(--s4); }
.tile__h { margin: 0 0 var(--s3); font-size: 22px; font-weight: 700; color: var(--phos); letter-spacing: .01em; }
.tile__l { margin: 0 0 16px; display: flex; gap: 10px; font-size: var(--t-label); color: var(--text); flex-wrap: wrap; line-height: 1.5; }
.tile__l i { color: var(--sage-dim); font-style: normal; }
.tile__l b { color: var(--phos); font-weight: 700; font-variant-numeric: tabular-nums; }
.tile--week { display: grid; place-items: center; background: var(--panel-2); }
.tile--week .tile__bg { position: static; width: 58%; height: auto; object-fit: contain; }

/* ---------- a window pane ---------- */
.pane {
  display: flex; flex-direction: column; min-width: 0;
  border-radius: var(--r); overflow: hidden;
  background: var(--panel);
  background-image: url(/img/tex/grain.png);
  background-blend-mode: soft-light;
}
.pane__bar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  background: var(--sage); min-height: 56px; padding: 0 12px 0 28px;
}
.pane__t { margin: 0; font-size: 22px; font-weight: 700; color: var(--on-sage); }
.pane__fold { appearance: none; border: 0; background: transparent; cursor: pointer; width: 44px; height: 44px; display: grid; place-items: center; border-radius: 8px; }
.pane__fold img { width: 24px; height: 24px; filter: brightness(0.25) saturate(0.4); transition: transform .16s; }
.pane__fold[aria-expanded="false"] img { transform: rotate(-90deg); }
.pane__fold:hover { background: #0003; }
.pane__fold:focus-visible { outline: 3px solid var(--on-sage); outline-offset: -3px; }
.pane__body { padding: var(--s4); display: flex; flex-direction: column; gap: var(--s3); flex: 1 1 auto; }
.pane__body[hidden] { display: none; }
.pane__lede { margin: 0; color: var(--text); }

.slot {
  margin: 0; display: flex; align-items: baseline; gap: var(--s3);
  background: var(--void); border-radius: var(--r);
  padding: 20px var(--s3); min-height: 84px;
}
.slot__k { color: var(--muted); font-size: var(--t-label); flex: 0 0 auto; }
.slot__v {
  font-size: var(--t-mint); color: var(--phos); font-weight: 700;
  min-width: 0; overflow-wrap: anywhere; user-select: all;
}
.slot__v.is-empty { color: var(--muted); font-size: var(--t-body); font-weight: 500; user-select: none; }

.pane__acts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2); }
.marks { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.mark {
  width: 56px; height: 56px; border-radius: var(--r);
  background: var(--sage);
  display: grid; place-items: center;
  transition: background .12s;
}
.mark img { width: 24px; height: 24px; }
.mark:hover { background: var(--sage-hi); }
.mark:focus-visible { outline: 3px solid var(--phos); outline-offset: 2px; }
.mark[aria-disabled="true"] { opacity: .58; pointer-events: none; }
.marks__keeper { margin: 0 0 0 auto; display: flex; align-items: baseline; gap: 12px; font-size: var(--t-small); min-width: 0; }
.marks__keeper span { color: var(--dim); }
.marks__keeper b { color: var(--text); font-weight: 700; overflow-wrap: anywhere; }
.fine { margin: auto 0 0; font-size: var(--t-small); color: var(--dim); line-height: 1.5; }

/* ---------- how it reads ---------- */
.step {
  background: var(--panel); border-radius: var(--r); overflow: hidden;
  display: flex; flex-direction: column;
}
.step img { width: 100%; height: 190px; object-fit: cover; }
.step h3 { margin: 0; padding: var(--s3) var(--s3) 8px; font-size: 22px; font-weight: 700; color: var(--phos); }
.step p { margin: 0; padding: 0 var(--s3) var(--s3); font-size: var(--t-label); color: var(--text); line-height: 1.5; }

/* ---------- the catalogue ---------- */
.grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s2); }
.card {
  background: var(--panel); border-radius: var(--r);
  padding: var(--s4); display: grid; gap: var(--s2);
  grid-template-rows: auto auto auto 1fr auto;
}
.card__art { width: 132px; height: 132px; object-fit: contain; opacity: .44; }
.card.is-on .card__art { opacity: 1; }
.card__n { margin: 0; font-size: 23px; font-weight: 700; color: var(--title); }
.card__p { margin: 0; font-size: var(--t-small); color: var(--dim); letter-spacing: .01em; }
.card__r { margin: 0; font-size: var(--t-label); color: var(--text); line-height: 1.5; }
.card__f { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); font-size: var(--t-small); }
.card__f span { color: var(--dim); }
.chip {
  padding: 8px 18px; border-radius: 8px; background: var(--panel-2); color: var(--dim);
  font-size: var(--t-small); white-space: nowrap;
}
.card.is-on .chip { background: var(--phos); color: var(--on-sage); }

/* ---------- the ledger ---------- */
.ledger { display: grid; gap: 0; }
.ledger__r {
  display: grid; grid-template-columns: 1.1fr 1fr 1fr 1fr 1.4fr; gap: var(--s2);
  padding: 16px 20px; border-bottom: 1px solid #ffffff22; font-size: var(--t-label); line-height: 1.5;
  align-items: baseline;
}
.ledger__r:last-child { border-bottom: 0; }
.ledger__r--h { color: var(--dim); font-size: var(--t-small); }
.ledger__r b { color: var(--phos); font-weight: 700; font-variant-numeric: tabular-nums; }
.ledger__r a { color: var(--sage-hi); overflow-wrap: anywhere; }
.empty { margin: 0; color: var(--dim); font-size: var(--t-label); line-height: 1.5; }

/* ---------- widths ---------- */
/* The two columns hold while the passport stays wide enough for its printed lines to be read.
   Below that the booklet takes the whole sheet and the readout follows under it. */
@media (max-width: 1199px) {
  :root { --t-display: 44px; --t-mint: 22px; --margin: 20px; }
  .row--a, .row--b { grid-template-columns: minmax(0, 1fr); }
  .band img { height: clamp(190px, 19vw, 320px); }
  .row--steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Under a thousand the spread is too small to read, so the booklet shows ONE page at a time and
   every overlay moves to that page's own measured fractions. */
@media (max-width: 999px) {
  /* the single page plate is cropped to the print: 800 of the 1800 wide spread, starting at 50 */
  .book__plate { aspect-ratio: 2 / 3; }
  .rows__r { font-size: clamp(16px, 2.6cqw, 22px); }
  .rows { left: 13.25%; width: 71.25%; }
  .photo { left: 18.88%; width: 58.25%; }
  .pages { left: 10%; top: 7%; width: 80%; height: 86%; }
  .book__specimen { left: 50%; }
  .ribbon { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
  .ribbon__s { aspect-ratio: 2 / 1; }
}
@media (max-width: 620px) {
  .read__r { flex-direction: column; align-items: flex-start; gap: 2px; }
  .read__r b { text-align: left; }
  /* a phone has no room for the key inside the field: the address takes the line and the key
     takes the next one, full width, where a thumb finds it */
  .field { flex-wrap: wrap; height: auto; padding: 0; gap: 10px; background: transparent; }
  .field:focus-within { box-shadow: none; }
  .field__in {
    flex: 1 0 100%; height: 56px; padding: 0 20px;
    background: var(--void); border-radius: var(--r);
  }
  .field__in:focus { box-shadow: inset 0 0 0 2px var(--phos); }
  .field__go { flex: 1 0 100%; height: 56px; border-radius: var(--r); }
}

@media (max-width: 820px) {
  :root { --t-display: 38px; --t-h2: 26px; --t-body: 19px; --t-label: 17px; --t-small: 16px; --s4: 24px; --margin: 14px; }
  .bar { flex-wrap: wrap; }
  .field { order: -1; width: 100%; flex: 1 0 100%; }
  .bar__nav { flex: 1 1 auto; justify-content: flex-start; }
  .bar__keys { flex: 0 0 auto; justify-content: flex-end; }
  .tabs { padding: 10px 12px 0; flex-wrap: wrap; }
  .tabs__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; flex: 1 0 100%; }
  .tab { padding: 0 16px; height: 52px; font-size: var(--t-small); border-radius: var(--r); }
  .lamps { flex: 1 0 100%; justify-content: flex-end; padding: 10px 0; }
  .grid, .row--steps { grid-template-columns: minmax(0, 1fr); }
  .pane__acts { grid-template-columns: minmax(0, 1fr); }
  .slot { flex-direction: column; gap: 8px; }
  .ledger__r { grid-template-columns: repeat(2, minmax(0, 1fr)); font-size: var(--t-small); }
  .marks__keeper { margin: 0; width: 100%; }
  .step img { height: 160px; }
  /* on a phone the passport is one page at a time, swiped */
  .book__keys { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* the pitch is the plate's own printed pitch and never changes: only the type gets smaller */
  .rows__r { font-size: clamp(16px, 5cqw, 20px); }
  .pages__grid { grid-template-columns: repeat(2, 1fr); }
}

/* the smallest plates leave the printed rules only about 22px apart, so the gap under the
   baseline shrinks with them and five rows still land on five rules */
@media (max-width: 480px) {
  .rows__r { line-height: 1.05; padding-bottom: 1.35cqh; }
}

@media (max-width: 400px) {
  :root { --margin: 8px; }
  .tabs { padding: 10px 8px 0; }
  .bar { padding: 12px 10px; }
  .sheet { padding: 10px; gap: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .scan { animation: none; }
  .pages__s.is-new { animation: none; }
  * { transition-duration: 0ms !important; }
}
