/* The AI Bubble Indicator. One phosphor screen, one container, one hue.
   The language is measured off art/ref/bbs-terminal.jpg (NOTE.md > Reference teardown): one text
   size, headings told apart by brightness alone, 70% of the sheet pure black, plates with a hatched
   field. The ARRANGEMENT is this page's own: the six constituents are the longest block on the
   page, so they are a row under the session instead of a third column that ran 700px past the
   other two.

   One type scale: 16 / 20 / 22 (the pixel face, on its own 11px grid) / 32 / 48.
   One spacing scale: 4 / 8 / 12 / 16 / 24 / 32 / 48. Nothing off these two lists. */

@font-face {
  font-family: "Iosevka SS11";
  src: url("/assets/fonts/iosevka-ss11-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Iosevka SS11";
  src: url("/assets/fonts/iosevka-ss11-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Departure Mono";
  src: url("/assets/fonts/departure-mono.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: dark;

  /* The one hue. Every step measured against #000: 15.4, 10.7, 8.8, 7.2 to one. The two quiet
     steps were lifted twice: 4.5 is the floor of the gate, not the target, and on a phosphor page
     a label at 5:1 still reads as switched off. */
  --void: #000000;
  --ink: #54fc54;
  --ink-2: #3fd44a;
  --ink-3: #39c047;
  --ink-4: #33ad3e;

  /* One container for the whole page: the session block and the room row share its edges. */
  --page: 1024px;
  --gutter: 24px;
  --col-you: 188px;   /* 46 native x 4 + the plate frame, so the avatar fits the rail exactly */
  --gap-col: 44px;

  /* The rasters. One native pixel of art = one block; every sprite is shown at a WHOLE multiple. */
  --px-plate: 3px;       /* the constituents, 46 x 28 native */
  --px-you: 4px;         /* the one avatar, 46 x 28 native */
  --banner-w: 744px;     /* 124 native x 6 */
  --banner-h: 156px;     /* 26 native x 6 */

  /* type */
  --t: 16px;
  --lh: 24px;
  --t-px: 22px;          /* the pixel face */
  --t-mid: 20px;
  --t-big: 24px;         /* the empty reading: a word, not a number, two steps under the number */
  --t-display: 48px;     /* the one display element on the screen */

  /* space */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s6: 24px;
  --s8: 32px;
  --s12: 48px;

  --row-h: 28px;         /* one row height for every label / value pair on the page */
  --lab-rail: 80px;      /* one left-hand line for the rail's labels, so the values after them
                            start on ONE vertical in BOTH blocks, whatever a value is */
  --lab-col: 232px;      /* one left-hand line for the session's labels */
}

* { box-sizing: border-box; }

html { background: var(--void); }

body {
  margin: 0;
  background: var(--void);
  color: var(--ink-2);
  font-family: "Iosevka SS11", ui-monospace, "SFMono-Regular", Consolas, monospace;
  font-size: var(--t);
  line-height: var(--lh);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.screen {
  min-height: 100vh;
  padding: var(--s4) 0 var(--s12);
}

/* The container. Both blocks below use it, so the page has ONE left edge and ONE right edge. */
.page,
.room-wrap {
  width: 100%;
  max-width: var(--page);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.page {
  display: grid;
  grid-template-columns: var(--col-you) minmax(0, 1fr);
  column-gap: var(--gap-col);
  align-items: start;
}
/* The session is first in the source (it is what a visitor came for, and on a phone it is the
   first screen), and second in the grid. */
.rail-you { grid-column: 1; grid-row: 1; }
.session  { grid-column: 2; grid-row: 1; min-width: 0; }

.room-wrap { margin-top: var(--s12); }

/* ---------- the pixel rasters ------------------------------------------------------------- */

.px {
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  display: block;
}

/* No glow on the strip: a drop-shadow on a pixel sprite is a blurred edge, and a blurred edge on
   a 6x sprite is six blurred pixels. The only glow left on the page is on the chart line. */
.banner-wrap { display: block; margin: 0 0 var(--s4); }
.banner {
  width: var(--banner-w);
  height: var(--banner-h);
  max-width: 100%;
}

/* ---------- type roles -------------------------------------------------------------------- */

.hi { color: var(--ink); margin: 0 0 var(--s4); }
.dim { color: var(--ink-3); margin: 0 0 var(--s4); }
p { margin: 0 0 var(--s4); }
/* A terminal column that runs 93 characters wide is not a terminal column: the prose stops at 76,
   which is 82% of the session and the longest line that still reads as one line. */
.blk p, .rail-note, .room-note, .prompt-hint, .reading-label { max-width: 76ch; }

.room,
.rail-head {
  font-family: "Departure Mono", "Iosevka SS11", monospace;
  font-size: var(--t-px);
  line-height: var(--s8);
  font-weight: 400;
  letter-spacing: 0.08em;
  color: var(--ink);
  margin: 0;
}

/* One logic for every rule on the page: it is set in the HEADING's own face at the HEADING's own
   size, and it carries exactly as many signs as the heading has letters, so it is exactly as wide
   as the heading it sits under. Nine for Inventory, eight for The Bank, eleven for In The Room. */
.rule {
  font-family: "Departure Mono", "Iosevka SS11", monospace;
  font-size: var(--t-px);
  line-height: var(--s6);
  color: var(--ink-4);
  margin: 0 0 var(--s3);
  letter-spacing: 0.08em;
  user-select: none;
  white-space: nowrap;
}

.echo {
  font-family: "Departure Mono", "Iosevka SS11", monospace;
  font-size: var(--t-px);
  line-height: var(--s8);
  letter-spacing: 0.08em;
  color: var(--ink-3);
  margin: 0 0 var(--s2);
}
.echo b { color: var(--ink); font-weight: 400; }

/* ---------- plates ------------------------------------------------------------------------ */

.plate { margin: 0; }

/* The border is counted ON TOP of the sprite, never out of it: with border-box a 2px frame ate two
   pixels of a 46 pixel sprite and the browser resampled it at 3.91x. That was the blur. */
.plate img {
  width: calc(46 * var(--px-plate) + 4px);
  height: calc(28 * var(--px-plate) + 4px);
  border: 2px solid var(--ink-4);
  /* His plates are not black inside the frame: the field behind every portrait measures luminance
     22 to 84 while the page around it is a flat 0. An even, regular hatch, 1 px on 3. */
  background: repeating-linear-gradient(45deg, #071f07 0 1px, #0d330d 1px 3px);
}
.plate-you img {
  width: calc(46 * var(--px-you) + 4px);
  height: calc(28 * var(--px-you) + 4px);
}

.cap {
  display: block;
  font-family: "Departure Mono", "Iosevka SS11", monospace;
  font-size: var(--t-px);
  line-height: var(--s6);
  letter-spacing: 0.08em;
  color: var(--ink-2);
  overflow-wrap: anywhere;
}
/* The avatar is the biggest thing in the rail, so its name gets the air to match it. */
.plate-you .cap { margin-top: var(--s3); }

/* ---------- the left rail: you ------------------------------------------------------------ */

.rail { min-width: 0; }
.rail-head { margin-top: var(--s8); }
.plate-you + .rail-head { margin-top: var(--s6); }

/* One grid, one fixed LABEL column, and the same label column in the bank block below it: that is
   what starts every value in the rail on one vertical line. Right-aligned values only lined up
   their last character, and with "not set" over "0.504 SOL" the eye reads the first one. */
.rail-rows {
  display: grid;
  grid-template-columns: var(--lab-rail) minmax(0, 1fr);
  column-gap: var(--s2);
  margin: 0;
}
.rail-row { display: contents; }
.rail-row dt,
.rail-row dd {
  margin: 0;
  min-height: var(--row-h);
  padding: 2px 0;
  overflow-wrap: anywhere;
}
.rail-row dt { color: var(--ink-3); }
.rail-row dd {
  color: var(--ink);
  /* the data is a step bigger than the words around it: the hint under the block is 16, this is 20 */
  font-size: var(--t-mid);
  line-height: var(--lh);
}
.rail-row dd.empty { color: var(--ink-4); }

/* A hint is not a reading: it keeps its distance and it never wears the value ink. */
.rail-note,
.room-note {
  color: var(--ink-3);
  margin: var(--s4) 0 0;
}

/* ---------- the room: six plates in a row, not a column ----------------------------------- */

.room-plates {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* Fixed plate columns, never 1fr: a fractional column puts a pixel sprite on a fractional x,
     and a pixel sprite on a fractional x is resampled, which is the blur all over again. */
  grid-template-columns: repeat(6, calc(46 * var(--px-plate) + 4px));
  gap: var(--s6);
}

/* Every plate is the same canvas: four fixed rows, so a nine-letter ticker cannot make one card
   taller than the next, and an empty slot still holds its place. */
.plate-btn {
  display: grid;
  grid-template-rows: calc(28 * var(--px-plate) + 4px) auto auto auto;
  /* The tallest card a state can make (a two line "waiting for a price") is the height of every
     card, and the lines stack from the top: fixed rows instead left a hole under a one line price. */
  min-height: calc(28 * var(--px-plate) + 4px + 24px + 48px + 24px + 3 * var(--s2));
  align-content: start;
  row-gap: var(--s2);
  width: 100%;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.plate-btn img { transition: border-color 0.18s; }
.plate-btn .cap { transition: color 0.18s; }
.plate-btn:hover img,
.plate-btn:focus-visible img { border-color: var(--ink); }
.plate-btn:hover .cap,
.plate-btn:focus-visible .cap { color: var(--ink); }
.plate-btn:active { transform: translateY(2px); }

.plate-price { display: block; color: var(--ink); overflow-wrap: anywhere; }
.plate-price.empty { color: var(--ink-4); }
td.empty { color: var(--ink-4); }
.plate-state { display: block; color: var(--ink-3); }
.plate-state.out {
  justify-self: start;
  background: var(--ink);
  color: var(--void);
  padding: 2px var(--s4);
  letter-spacing: 0.08em;
}

/* ---------- the session ------------------------------------------------------------------- */

.transcript { min-width: 0; }

.blk {
  margin: 0 0 var(--s6);
  animation: print 0.2s ease-out both;
}
@keyframes print {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .blk { animation: none; }
}

.room { margin-bottom: var(--s1); }
/* The reading the session prints as it connects, so it sits tighter than a printed block. */
.blk-reading { margin-bottom: var(--s4); animation: none; }
.blk-boot p { margin-bottom: var(--s4); }
.blk-boot .room { margin-top: var(--s1); }
.room-list button { margin: 0; }

/* the one display element on the screen */
.reading { margin: 0 0 var(--s3); }
/* The hierarchy of the one live thing on the page, in three steps that cannot be confused: what
   this is (16, quiet), what it reads (48, or 24 when there is nothing to read), what that means
   (16, quieter). The heading stays UNDER the value in size, or it is not a heading. */
.reading-head {
  font-size: var(--t);
  line-height: var(--lh);
  letter-spacing: 0.08em;
  font-weight: 400;
  color: var(--ink-2);
  margin: 0 0 var(--s1);
}
.reading-value {
  font-family: "Departure Mono", "Iosevka SS11", monospace;
  font-size: var(--t-display);
  line-height: var(--t-display);
  color: var(--ink);
  display: block;
}
/* "not yet" is an empty value, not a headline: it prints at the size of a heading, not at the size
   of the number it is standing in for. */
.reading-value.empty {
  color: var(--ink-4);
  font-size: var(--t-big);
  line-height: var(--t-big);
}
.reading-label { display: block; color: var(--ink-3); margin-top: var(--s2); }
.reading-value.flash { animation: flash 0.5s steps(2, end) 1; }
@keyframes flash { 0%, 49% { color: var(--void); background: var(--ink); } 50%, 100% { } }
@media (prefers-reduced-motion: reduce) { .reading-value.flash { animation: none; } }

/* One grid for every label / value pair the session prints: one left line, one right line, one
   row height, whatever the block. */
.rows {
  display: grid;
  grid-template-columns: var(--lab-col) minmax(0, 1fr);
  /* Full width of the session: the values line up with the right edge of the strip above them and
     the prompt below them, so the block has ONE right edge instead of ending in mid air. */
  margin: 0 0 var(--s4);
}
.row { display: contents; }
.row dt,
.row dd {
  margin: 0;
  min-height: var(--row-h);
  padding: 2px 0;
}
.row dt { color: var(--ink-3); }
.row dd { color: var(--ink); text-align: right; overflow-wrap: anywhere; min-width: 0; }
.row dd.empty { color: var(--ink-4); }

/* No rules between rows: his sheet draws none, and a rule would make every cell a box that owes
   its text an em of air on each side. The leading does the separating, as it does in a terminal. */
table { border-collapse: collapse; width: 100%; margin: 0 0 var(--s4); }
th, td { text-align: left; padding: var(--s1) var(--s6) var(--s1) 0; vertical-align: top; }
th:last-child, td:last-child { padding-right: 0; text-align: right; }
th { color: var(--ink-3); font-weight: 400; }
td { color: var(--ink-2); }
td b { color: var(--ink); font-weight: 400; }
td.nowrap, th.nowrap { white-space: nowrap; }

/* Counted is the quiet state, so it is quiet: plain text in the label ink. Only a constituent that
   has LEFT the basket takes the knocked-out block, because that is the one worth looking at. */
.tag { color: var(--ink-3); letter-spacing: 0.06em; }
.tag.off {
  display: inline-block;
  background: var(--ink);
  color: var(--void);
  padding: 2px var(--s4);
  letter-spacing: 0.06em;
}

canvas.chart {
  display: block;
  width: 100%;
  height: 180px;
  margin: var(--s2) 0 var(--s4);
}

/* ---------- the prompt -------------------------------------------------------------------- */

/* Three columns and two rows: the mark, the field, the button, and the hint parked under the
   FIELD, so the hint and the typed text start on the same vertical line. */
.prompt {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  column-gap: var(--s3);
  align-items: center;
  margin-top: var(--s2);
}
.prompt-mark {
  font-family: "Departure Mono", "Iosevka SS11", monospace;
  font-size: var(--t-px);
  line-height: 1;
  color: var(--ink);
}
.prompt-input {
  min-width: 0;
  height: var(--s12);
  background: transparent;
  border: 0;
  border-bottom: 2px solid var(--ink-4);
  color: var(--ink);
  font: inherit;
  /* no side padding: the typed text, the rule under it and the hint under that all start on the
     same vertical. With 16px of padding the hint sat 16px right of where the field began. */
  padding: 0;
  caret-color: var(--ink);
  transition: border-color 0.18s;
}
.prompt-input::placeholder { color: var(--ink-4); }
.prompt-input:focus { outline: none; border-bottom-color: var(--ink); }
/* The Run button is the same object as every other control on the page: a framed word. A filled
   block here shouted louder than the reading itself. */
.prompt-send {
  /* 0.5em over and under the pixel face, measured: a 48px box with 22px type left 10px and the
     kit asks for 11 (RULES/05_TYPE_AND_SURFACES.md > Inner padding). */
  min-height: var(--s12);
  min-width: 96px;
  padding: var(--s3) var(--s6);
  background: none;
  /* a step quieter than the reading: the one thing allowed to be the brightest object on this
     page is the number */
  color: var(--ink-2);
  border: 2px solid var(--ink-4);
  font-family: "Departure Mono", "Iosevka SS11", monospace;
  font-size: var(--t-px);
  letter-spacing: 0.08em;
  cursor: pointer;
  transition: border-color 0.18s, transform 0.08s;
}
.prompt-send:hover, .prompt-send:focus-visible { border-color: var(--ink); color: var(--ink); }
.prompt-send:active { transform: translateY(2px); }
.prompt-hint {
  grid-column: 2;
  grid-row: 2;
  color: var(--ink-3);
  margin: var(--s2) 0 0;
}

/* The one thing on a board that is always alive: the block cursor beside the prompt. It does NOT
   stand down while the field has focus, because the field has focus from the moment the page
   loads, and hiding it there left the whole page without a single moving pixel. */
.cursor::after {
  content: "";
  display: inline-block;
  width: 11px;
  height: 22px;
  margin-left: 6px;
  background: var(--ink);
  vertical-align: -4px;
  /* 1.2s, not 1.06s: the motion check samples every 2s, and 2.12s of sampler against a 1.06s
     blink is exactly two periods, so the cursor read as dead while it was blinking fine. */
  animation: blink 1.2s steps(1, end) infinite;
}
@keyframes blink { 0%, 50% { opacity: 1; } 51%, 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .cursor::after { animation: none; } }

/* ---------- words that act ---------------------------------------------------------------- */

.inline-cmd {
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  transition: background-color 0.12s, color 0.12s;
}
.inline-cmd:hover,
.inline-cmd:focus-visible { background: var(--ink); color: var(--void); text-decoration: none; }
.inline-cmd:active { background: var(--ink-3); color: var(--void); }

a { color: var(--ink); text-underline-offset: 3px; overflow-wrap: anywhere; transition: background-color 0.12s, color 0.12s; }
a:hover, a:focus-visible { background: var(--ink); color: var(--void); text-decoration: none; }
a:active { background: var(--ink-3); color: var(--void); }

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

/* Selecting the mint must not paint the browser's blue across the one hue the page has. */
::selection { background: var(--ink); color: var(--void); }

/* ---------- the node card: the only links on the page ------------------------------------- */

.mint {
  display: flex;
  align-items: stretch;
  gap: var(--s3);
  margin: 0 0 var(--s4);
}
.mint-value {
  flex: 1 1 auto;
  min-width: 0;
  border: 2px solid var(--ink-4);
  padding: var(--s3) var(--s4);
  color: var(--ink);
  background: transparent;
  overflow-wrap: anywhere;
  user-select: all;
  font: inherit;
}
.mint-value.empty { color: var(--ink-4); }
.copy {
  flex: 0 0 auto;
  min-height: var(--s12);
  padding: var(--s3) var(--s6);
  background: none;
  color: var(--ink);
  border: 2px solid var(--ink-4);
  font-family: "Departure Mono", "Iosevka SS11", monospace;
  font-size: var(--t-px);
  letter-spacing: 0.08em;
  cursor: pointer;
  transition: border-color 0.18s, transform 0.08s;
}
.copy:hover { border-color: var(--ink); }
.copy:active { transform: translateY(2px); }
.copy[disabled] { color: var(--ink-4); cursor: not-allowed; }

/* Two by two: four across cut every label in half at this column width. */
.keys {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s3);
  margin: 0 0 var(--s4);
}
.key {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: var(--s12);
  padding: var(--s3) var(--s4);
  /* A button takes the browser grey without this, which the audit caught at 3.92:1 */
  background: none;
  font: inherit;
  cursor: pointer;
  border: 2px solid var(--ink-4);
  color: var(--ink);
  text-decoration: none;
  font-family: "Departure Mono", "Iosevka SS11", monospace;
  font-size: var(--t-px);
  letter-spacing: 0.06em;
  transition: border-color 0.18s, transform 0.08s;
}
.key img { width: 22px; height: 22px; image-rendering: auto; flex: 0 0 auto; }
.key:hover, .key:focus-visible { border-color: var(--ink); background: none; color: var(--ink); }
.key:active { transform: translateY(2px); }
.key[aria-disabled="true"] {
  color: var(--ink-4);
  border-color: rgba(51, 173, 62, 0.5);
  pointer-events: none;
}
.key[aria-disabled="true"] img { opacity: 0.74; }

/* ---------- the mine form ----------------------------------------------------------------- */

.addr-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s3);
  margin: 0 0 var(--s4);
}
.addr-form .addr-input { grid-column: 1 / -1; }
.addr-input {
  min-width: 0;
  height: var(--s12);
  background: transparent;
  border: 2px solid var(--ink-4);
  color: var(--ink);
  font: inherit;
  padding: 0 var(--s4);
}
.addr-input::placeholder { color: var(--ink-4); }
.addr-input:focus { outline: none; border-color: var(--ink); }

.noscript { color: var(--ink-2); max-width: 68ch; margin: var(--s6) auto; padding: 0 var(--s4); }

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

/* Under the container width the two columns stack, the session first. Every width keeps ONE
   container, so the left edge of the rail and the left edge of the room row never disagree. */
@media (max-width: 1023px) {
  :root { --page: 792px; --banner-w: 744px; --banner-h: 156px; --px-plate: 4px; }
  .page { display: block; }
  .rail-you { margin-top: var(--s12); }
  .room-plates { grid-template-columns: repeat(3, calc(46 * var(--px-plate) + 4px)); }
  .rail-rows { max-width: 420px; }
}

@media (max-width: 791px) {
  :root { --banner-w: 620px; --banner-h: 130px; }
}

@media (max-width: 667px) {
  :root { --banner-w: 496px; --banner-h: 104px; }
  .room-plates { grid-template-columns: repeat(2, calc(46 * var(--px-plate) + 4px)); }
}

/* Below this the narrow raster takes over: 84 x 18 native, so the strip is still a whole multiple
   of its own pixels on a phone. */
@media (max-width: 559px) {
  :root {
    --gutter: var(--s4);
    --banner-w: 336px;
    --banner-h: 72px;
    --px-plate: 2px;
    --t-display: var(--t-big);
  }
  .screen { padding: var(--s4) 0 var(--s8); }
  /* auto, never max-content: a max-content value track cannot give ground, and "30% of the bank"
     then pushed 16px of the rules block off a 320px screen. */
  .rows { grid-template-columns: minmax(0, 1fr) auto; max-width: none; }
  .room-plates { grid-template-columns: 1fr; gap: var(--s6); }
  /* On one column a plate turns on its side, so six of them are still one thumb of scrolling. */
  .plate-member .plate-btn {
    grid-template-columns: calc(46 * var(--px-plate) + 4px) minmax(0, 1fr);
    grid-template-rows: var(--s6) var(--s6) var(--s8);
    /* the standing card's height belongs to the standing card: on its side the rows decide */
    min-height: 0;
    column-gap: var(--s4);
    align-items: start;
  }
  .plate-member .plate-btn img { grid-row: 1 / span 3; }
  .keys { grid-template-columns: 1fr; }
  .mint { flex-direction: column; }
  .copy { width: 100%; }
  .prompt { grid-template-columns: auto minmax(0, 1fr); }
  .prompt-send { grid-column: 1 / -1; grid-row: 2; margin-top: var(--s3); width: 100%; }
  .prompt-hint { grid-row: 3; }

  /* A five column table is sideways scroll on a phone, which is a failure, not a note. Every row
     prints as its own small block with its heading beside each value. */
  table.stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  table.stack, table.stack tbody, table.stack tr, table.stack td { display: block; width: 100%; }
  table.stack tr { margin-bottom: var(--s4); }
  table.stack td { padding: 2px 0; text-align: left; display: grid; grid-template-columns: 1fr auto; gap: var(--s3); }
  table.stack td::before { content: attr(data-label); color: var(--ink-3); }
  table.stack td:first-child { padding-bottom: var(--s1); }
  table.stack td:first-child::before { content: none; }
  table.stack td.wide { display: block; }
  table.stack td.wide::before { content: none; }
}

@media (max-width: 367px) {
  :root { --banner-w: 252px; --banner-h: 54px; }
}
