/* Self-hosted, so no visitor's IP goes to a third party before they
   could agree to it -- and so the pixel font cannot be missing.

   Only the faces serfies.css actually sets, latin only:
     IBM Plex Mono 400 / 600 / 700, Silkscreen 400.
   No pixel-font element is ever set bold, so Silkscreen 700 is not
   here; if one ever is, add the face rather than letting the browser
   synthesise it -- faux bold on a pixel font looks like a bug.

   font-display: swap keeps text visible while the face loads, which
   is what the Google-hosted version did too. */
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("./assets/fonts/plex-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("./assets/fonts/plex-600.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Silkscreen";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("./assets/fonts/silkscreen-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Silkscreen";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("./assets/fonts/silkscreen-700.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* --- the four that move, per load. THEHORROR paints first. --- */
  --ink: #000000;
  --a:   #33ffff;
  --b:   #ff3366;
  --l:   #f2f0f8;
  --pat: #33ffff;      /* the serfie's own background pattern colour */

  /* --- the three that never move --- */
  --alarm:  #ff0042;
  --scan:   #00ff48;
  --notice: #f5f23c;

  --dim:    rgba(242,240,248,.62);
  --dimmer: rgba(242,240,248,.38);
  --edge:   rgba(242,240,248,.16);
  --pat-16: rgba(51,255,255,.16);

  --panel: rgba(0,0,0,.45);
  --machine: #8f8f93;   /* the painted chassis, the one grey in the work */

  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Consolas, monospace;
  --pixel: "Silkscreen", var(--mono);

  /* --- the eleven steps. Every font-size on this page is one of these. --- */
  --t-display:      clamp(19px, 3.4vw, 38px);
  --t-display-page: clamp(22px, 4vw, 34px);
  --t-headline:     26px;
  --t-headline-sm:  22px;
  --t-figure:       20px;
  --t-title:        17px;
  --t-title-sm:     15px;
  --t-nav:          12px;
  --t-body:         14px;
  --t-body-sm:      13px;
  --t-label:        11px;
  --t-label-sm:     10px;

  /* --- spacing --- */
  --s-hair: 2px;
  --s-xs:   6px;
  --s-sm:   10px;
  --s-md:   16px;
  --s-lg:   22px;
  --s-xl:   34px;
  --s-section: 90px;
  --s-2xl:  56px;          /* between --s-xl and --s-section */

  /* --- aliases for names the stylesheet already uses --- */
  /* These five were referenced but never defined, so every declaration that
     used one was thrown away by the browser: the wallet's "connected" dot had
     no colour at all, three font sizes fell back to whatever they inherited,
     and .gallery lost its padding entirely (one invalid var voids the whole
     shorthand). Defined here as the nearest existing token, which restores
     the evident intent without inventing a new scale. */
  --go:     var(--scan);       /* the one green kept for "this will go through" */
  --t-sm:   var(--t-body-sm);  /* 13px */
  --t-h2:   var(--t-headline-sm);
  --t-h3:   var(--t-title);

  --shadow: 5px 5px 0 rgba(0,0,0,.65);
  --shadow-in: 3px 3px 0 rgba(0,0,0,.65);

  --maxw: 1140px;
}

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

/* [hidden] is only a UA rule at display:none specificity 0-0-1, so any class
   that sets display beats it. Everything on this page that is toggled --
   the mint panel, the entrant row, the rain canvas -- relies on it holding. */
[hidden] { display: none !important; }

html { background: var(--ink); -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--l);
  font-family: var(--mono);
  font-size: var(--t-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* the ground is the collection's own dot grid at 22px, the same rhythm the
     work uses, in the drawn colorway's pattern colour */
  background-image: radial-gradient(var(--pat-16) 1px, transparent 1px);
  background-size: 22px 22px;
  overflow-x: hidden;
}
body.locked { overflow: hidden; }

::selection { background: var(--a); color: var(--ink); }
b { font-weight: 600; }
a { color: var(--b); }

/* the colorway swap should read as a repaint, not as a flicker */
@media (prefers-reduced-motion: no-preference) {
  body, .fr, .btn, .panel { transition: background-color .3s, border-color .3s, color .3s; }
}

/* ------------------------------------------------------------- type classes
   Named for the ramp steps in DESIGN.md so the hierarchy is legible in the
   markup and no size is invented at the call site. */
.t-display {
  font-family: var(--pixel);
  font-size: var(--t-display);
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: .01em;
}
.t-display-page {
  font-family: var(--pixel);
  font-size: var(--t-display-page);
  font-weight: 400;
  letter-spacing: .03em;
  line-height: 1.2;
}
.t-headline {
  font-family: var(--pixel);
  font-size: var(--t-headline);
  font-weight: 400;
  line-height: 1.1;
}
.t-figure {
  font-family: var(--pixel);
  font-size: var(--t-figure);
  font-weight: 400;
}
.t-title {
  font-family: var(--pixel);
  font-size: var(--t-title);
  font-weight: 400;
  letter-spacing: .05em;
  text-transform: uppercase;
}
.t-title-sm {
  font-family: var(--pixel);
  font-size: var(--t-title-sm);
  font-weight: 400;
  letter-spacing: .06em;
}
.t-label {
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.t-label-sm {
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  font-weight: 400;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.t-body-sm { font-size: var(--t-body-sm); line-height: 1.6; }

/* ==================================================================== shell */
.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--s-lg) var(--s-section);
}

/* ------------------------------------------------------------------ wordmark
   The wordmark is a drawn asset, not type. It ships as white pixels on
   transparent, so it is punched through as a mask and the colorway paints it
   — which is how it becomes the outline the boards were drawn with. */
header.head { padding: 52px 0 var(--s-xl); text-align: center; }
h1.wm-wrap { margin: 0; font-size: 0; line-height: 0; }
h1.wm-wrap a { display: block; }
.wordmark {
  display: block;
  width: min(560px, 84vw);
  aspect-ratio: 736 / 149;
  margin: 0 auto;
  background: var(--b);
  -webkit-mask: url('./assets/serfies-outline.png') no-repeat center / contain;
          mask: url('./assets/serfies-outline.png') no-repeat center / contain;
}
.claim-line {
  max-width: 46ch;
  margin: var(--s-lg) auto 0;
  font-family: var(--mono);
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--dim);
}
.tagline {
  margin: var(--s-sm) 0 0;
  font-family: var(--pixel);
  font-size: var(--t-title);
  font-weight: 400;
  letter-spacing: .05em;
  color: var(--l);
  line-height: 1.3;
}
.tagline sup { font-size: .55em; vertical-align: super; }

/* ------------------------------------------------------------ serfie preview
   The frame is the collection's own crop: a hard 3px accent rule, square,
   no shadow inside the art. Clicking it draws a new face — which is the whole
   reason it is a button and not an image. */
.serfie-wrap { display: flex; justify-content: center; margin: var(--s-xs) 0 0; }
.frame {
  appearance: none;
  position: relative;
  display: block;
  padding: 0;
  width: min(420px, 80vw);
  aspect-ratio: 1;
  border: 1px solid var(--b);
  background: var(--ink);
  box-shadow: var(--shadow);
  cursor: pointer;
  overflow: hidden;
}
.frame:active { transform: translate(2px, 2px); box-shadow: var(--shadow-in); }
.frame:focus-visible { outline: 3px solid var(--a); outline-offset: 3px; }
.frame > svg { display: block; width: 100%; height: 100%; }
/* the same, one level down: the mint card and the gallery wrap the drawing in
   an .art so it can be replaced without touching the frame */
.frame > .art { position: absolute; inset: 0; }
.frame > .art > svg { display: block; width: 100%; height: 100%; }


.cw-caption {
  max-width: 54ch;
  margin: var(--s-md) auto 0;
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .1em;
  text-transform: uppercase;
  line-height: 1.7;
  color: var(--dim);
}
.cw-caption b { color: var(--a); font-weight: 400; }

/* ------------------------------------------------------------------ buttons */
.btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-sm);
  border: 0;
  background: var(--b);
  color: var(--ink);
  font-family: var(--pixel);
  font-size: var(--t-title);
  font-weight: 400;
  letter-spacing: .05em;
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1;
  padding: 19px 30px;
  cursor: pointer;
  box-shadow: var(--shadow);
}
.btn:hover { background: var(--a); }
.btn:active { transform: translate(2px, 2px); box-shadow: var(--shadow-in); }
.btn:focus-visible { outline: 3px solid var(--b); outline-offset: 3px; }
/* the one green the collection keeps for a control that will go through */
.btn.go { background: var(--scan); color: #000; }
.btn.go:hover { background: var(--l); }

.btn[disabled] {
  background: transparent;
  border: 3px solid var(--edge);
  color: var(--dimmer);
  padding: 16px 27px;
  box-shadow: none;
  cursor: not-allowed;
  transform: none;
}
.btn.ghost {
  background: transparent;
  border: 3px solid var(--edge);
  color: var(--a);
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: .1em;
  padding: 14px var(--s-lg);
  box-shadow: none;
}
.btn.ghost:hover { background: var(--a); color: var(--ink); border-color: var(--a); }
.btn.ghost:active { transform: translate(2px, 2px); box-shadow: none; }
.btn.block { width: 100%; }
.btn svg { width: 14px; height: 14px; fill: currentColor; flex: 0 0 auto; }
/* "Share on" then the mark itself: the logo is the word */
.btn .x-mark { width: 13px; height: 13px; }

.cta-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: stretch;      /* a secondary button is not a shorter button */
  gap: var(--s-md);
  margin: var(--s-xl) 0 0;
}

/* ------------------------------------------------------------------- stages */
.stage { display: none; }
.stage.on { display: block; }

.sec { margin: var(--s-section) 0 0; }
/* the mint panel answers the caption above it, so it sits close to it */
#phaseTable { margin-top: var(--s-xl); }
.sec-head {
  display: flex;
  align-items: baseline;
  gap: var(--s-md);
  margin: 0 0 var(--s-lg);
}
.sec-head h2 {
  margin: 0;
  font-family: var(--pixel);
  font-size: var(--t-display-page);
  font-weight: 400;
  letter-spacing: .03em;
  color: var(--l);
  line-height: 1.2;
  text-wrap: balance;
}
.sec-head .rule { flex: 1; height: 3px; background: var(--edge); }
.sec-head .tag {
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
  padding: 5px 9px;
  white-space: nowrap;
}

.eyebrow {
  margin: 0 0 var(--s-sm);
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
}
.eyebrow .n {
  display: inline-block;
  margin-right: var(--s-sm);
  padding: 2px var(--s-xs);
  background: var(--b);
  color: var(--ink);
}
.lede { max-width: 62ch; margin: 0 auto; color: var(--dim); }

/* ------------------------------------------------------------------- the drop
   What this is, and the list of what it is not. The list is the loud half, so
   the prose above it stays quiet and the claims get the accent. */
.drop { max-width: 68ch; margin: var(--s-lg) auto 0; }
.drop p { margin: 0 0 var(--s-md); color: var(--dim); text-align: center; }
.drop p b { color: var(--l); }

.claims {
  list-style: none;
  margin: var(--s-lg) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 3px;
}
@media (max-width: 620px) { .claims { grid-template-columns: minmax(0, 1fr) } }
.claims li {
  display: flex;
  align-items: baseline;
  gap: var(--s-sm);
  padding: 9px 12px;
  background: rgba(0,0,0,.4);
  border: 3px solid var(--edge);
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
}
.claims li::before {
  content: "";
  flex: 0 0 6px;
  height: 6px;
  margin-top: 5px;
  background: var(--b);
}
/* the one that is a sentence rather than a claim runs the full width */
.claims li.wide {
  grid-column: 1 / -1;
  border-color: var(--b);
  text-transform: none;
  letter-spacing: .02em;
  font-size: var(--t-body-sm);
  line-height: 1.65;
  color: var(--dim);
}
.cta-row + .lede { margin-top: var(--s-lg); }
.lede b { color: var(--l); }
.centered { text-align: center; }

/* =========================================================== the laptop
   The chassis is not drawn in code and never was: Website/Laptop.png is the
   artist's own painted machine, run through the collection's own tracer, so
   the edges on screen are the edges of the drawing. It wears the outline the
   rest of the work wears; the glass is placed from the trace, not by hand.
   See build/trace_laptop.py. */
.laptop {
  position: relative;
  width: 100%;
  max-width: 1200px;
  margin: var(--s-xl) auto 0;
}
.laptop-art svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}
.laptop .screen {
  position: absolute;
  overflow: hidden;
  background: var(--dc-app, #16181d);
  outline: 3px solid var(--a);
  outline-offset: 0;
}
.laptop .glass {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  background:
    repeating-linear-gradient(to bottom,
      rgba(255,255,255,.035) 0 1px, transparent 1px 3px),
    linear-gradient(115deg, rgba(255,255,255,.07) 0 22%, transparent 42%);
}

/* The narrow view used to hide the machine and give the client a plain
   box. It is zoomed instead now -- see "the narrow view" at the end of
   this file. */

/* The trackpad, relabelled. Position and size come from the trace, so it
   lands on the shape the artist drew rather than near it. */
.deck-back {
  position: absolute;
  z-index: 6;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: var(--a);
  border: 0;
  color: var(--ink);
  font-family: var(--pixel);
  /* it has to sit inside a key 4.4% of the laptop wide, so it is sized to
     the key rather than to the page */
  font-size: clamp(4px, .62vw, 9px);
  letter-spacing: 0;
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
}
.deck-back:hover { background: var(--l); }
.deck-back:active { transform: translate(1px, 1px); }
.deck-back:focus-visible { outline: 3px solid var(--b); outline-offset: 2px; }
/* .deck-back stays on a phone now: the key is drawn on the machine and
   hiding it left a blank key. See "the narrow view" below. */

/* ---------------------------------------------------------- the chat client
   A rebuilt client, not a screenshot: it keeps its own type scale and its own
   colours, because it is a depiction of somebody else's software sitting on a
   screen inside the artwork. The two list embeds are live controls. */
.dc {
  /* The client keeps its own palette on purpose. It is a depiction of
     somebody else's software sitting on a screen inside the artwork, so it
     must NOT wear the SERFIES tokens — a chat client in the drawn colorway
     would stop reading as a chat client and the joke would go with it.
     Declared once here rather than scattered through the rules below. */
  --dc-app: #16181d;
  --dc-panel: #1b1d23;
  --dc-rail: #0d0e11;
  --dc-foot: #14151a;
  --dc-line: #101114;
  --dc-line-2: #2a2d34;
  --dc-slot: #24262c;
  --dc-slot-2: #2b2d33;
  --dc-slot-on: #33363d;
  --dc-slot-off: #34363c;
  --dc-btn: #4a4d55;
  --dc-btn-hover: #5b5f68;
  --dc-text: #f2f3f5;
  --dc-text-2: #dbdee1;
  --dc-text-3: #cdd0d6;
  --dc-text-4: #b5bac1;
  --dc-text-5: #b6bac1;
  --dc-mute: #9aa0a9;
  --dc-mute-2: #8d939d;
  --dc-mute-3: #6d7178;
  --dc-mute-4: #7b7f88;
  --dc-brand: #f0295e;
  --dc-blurple: #5865f2;
  --dc-embed: #00a8fc;
  --dc-green: #57f287;
  --dc-yellow: #fee75c;
  --dc-go: #248046;
  --dc-go-hover: #1f6f3c;
  --dc-blurple-hover: #4752c4;
  /* role colours, the client's own convention: a name is worn, not styled */
  --dc-role-admin: #ed4245;
  --dc-role-famous: #c39cff;
  --dc-role-serf: #7ee787;
  --dc-white: #ffffff;
  --dc-blurple-16: rgba(88,101,242,.28);
  --dc-white-05: rgba(255,255,255,.05);

  display: grid;
  /* auto, not fixed: the widths live on the children (.dc-rail, .dc-side,
     .dc-members) so that hiding one of them collapses its column. A fixed
     track would stay 190px wide with nothing in it -- and .dc cannot be
     re-columned by a container query, because it IS the container. */
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  height: 100%;
  background: var(--dc-app);
  color: var(--dc-text-2);
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  font-size: 11.5px;
  line-height: 1.38;
  letter-spacing: 0;
  text-transform: none;
  container-type: inline-size;
}
.dc * { box-sizing: border-box; }

.dc-rail {
  width: 54px;
  background: var(--dc-rail);
  padding: 8px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  overflow: hidden;
}
.dc-rail hr { width: 26px; height: 1px; border: 0; background: var(--dc-line-2); margin: 1px 0; }
.dc-server {
  appearance: none;
  width: 36px; height: 36px;
  flex: 0 0 36px;
  border: 0;
  border-radius: 50%;
  background: var(--dc-slot);
  color: var(--dc-text-5);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.dc-server.on { background: var(--dc-brand); color: var(--dc-white); border-radius: 30%; }
/* a server whose icon is artwork shows the artwork, square, and nothing round
   or coloured behind it */
.dc-server.has-img { background: none; border-radius: 0; }
.dc-server.has-img:hover { border-radius: 0; }
.dc-server img {
  /* The PFP is a full-bleed square whose corner brackets run right to the
     edge, so a rounded crop ate them. Contained inside the slot instead, with
     the artwork's own black behind it, the whole mark survives. */
  width: 36px;
  height: 36px;
  object-fit: cover;
  border-radius: inherit;
  display: block;
}
.dc-server.has-img img { border-radius: 0; }
.dc-server:hover { border-radius: 30%; }

.dc-side { width: 190px; background: var(--dc-panel); display: flex; flex-direction: column; min-width: 0; min-height: 0; }
/* the server banner with the guild name sitting on it, the way a client shows
   one -- the name reads off a scrim rather than off the artwork */
.dc-guildwrap { position: relative; border-bottom: 1px solid var(--dc-line); }
.dc-banner {
  display: block;
  width: 100%;
  height: 70px;
  object-fit: cover;
  object-position: center 35%;
  background: var(--dc-rail);
}
.dc-guild {
  position: absolute;
  inset: 0 0 auto 0;
  padding: 9px 12px 16px;
  background: linear-gradient(rgba(0,0,0,.82) 40%, transparent);
  font-size: 13px;
  font-weight: 700;
  color: var(--dc-text);
  display: flex;
  justify-content: space-between;
  text-shadow: 0 1px 3px rgba(0,0,0,.9);
}
.dc-guild span { color: var(--dc-mute-2); }
.dc-chans { flex: 1; min-height: 0; overflow-y: auto; padding: 8px 6px; }
.dc-cat {
  padding: 12px 6px 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--dc-mute-2);
}
.dc-chan {
  appearance: none;
  width: 100%;
  border: 0;
  background: transparent;
  color: var(--dc-mute);
  font: inherit;
  text-align: left;
  padding: 5px 7px;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 5px;
}
.dc-chan i { color: var(--dc-mute-3); font-style: normal; font-weight: 700; }
.dc-chan:hover { background: var(--dc-slot); color: var(--dc-text-2); }
/* Only the two raffle channels lead anywhere. The rest sit a shade back and
   do not light up, so the pair that is clickable is the pair that looks it. */
.dc-chan.idle { color: var(--dc-mute-3); cursor: default; }
.dc-chan.idle:hover { background: transparent; color: var(--dc-mute-3); }
.dc-chan.on { background: var(--dc-slot-on); color: var(--dc-white); }
.dc-chan .badge {
  margin-left: auto;
  background: var(--dc-brand);
  color: var(--dc-white);
  font-size: 10px;
  font-weight: 700;
  padding: 0 6px;
  border-radius: 8px;
}
.dc-me {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 9px;
  background: var(--dc-foot);
  border-top: 1px solid var(--dc-line);
  min-width: 0;
}
.dc-me .who { display: grid; min-width: 0; }
.dc-me .nm {
  font-size: 11px;
  color: var(--dc-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dc-me .st { font-size: 9px; color: var(--dc-mute-2); }

/* every avatar is a real generated serfie, cropped to the face. The sizes are
   the ones a real client uses -- at 22px the face had nowhere to live. */
.av {
  width: 40px; height: 40px;
  flex: 0 0 40px;
  border-radius: 50%;
  background: var(--dc-slot-2);
  overflow: hidden;
  display: block;
}
.av svg { width: 100%; height: 100%; display: block; }
/* the restroke that makes the drawing survive being 32px across */
.av svg [stroke] { stroke-width: 70; }

.dc-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--dc-app); }
.dc-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;      /* the tabs take a full row of their own */
  gap: 6px;
  padding: 10px 13px;
  border-bottom: 1px solid var(--dc-line);
  font-weight: 700;
  color: var(--dc-text);
  flex: 0 0 auto;
}
.dc-head i { color: var(--dc-mute-3); font-style: normal; }
/* a channel name is one token; breaking it mid-word reads as a layout fault */
.dc-head > span:first-of-type { white-space: nowrap; }
.dc-compose #chanFoot { white-space: nowrap; }
.dc-head .topic {
  border-left: 1px solid var(--dc-line-2);
  margin-left: 6px;
  padding-left: 9px;
  font-size: 11px;
  font-weight: 400;
  color: var(--dc-mute-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dc-msgs { flex: 1; min-height: 0; overflow-y: auto; padding: 10px 12px 4px; }
.dc-chan { position: relative; }
.msg { display: flex; gap: 9px; margin-bottom: 11px; }
.msg > div { min-width: 0; flex: 1; }
.who-line { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.who-line b { color: var(--dc-text); font-size: 13px; }
.who-line time { font-size: 10px; color: var(--dc-mute-2); }
.who-line .bot {
  background: var(--dc-blurple);
  color: var(--dc-white);
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 3px;
}
.msg p { margin: 2px 0 0; color: var(--dc-text-3); }
.msg p + p { margin-top: 6px; }

/* a role colour applies to the name wherever it appears */
.r-admin  { color: var(--dc-role-admin) !important; }
.r-bot    { color: var(--dc-role-admin) !important; }
.r-famous { color: var(--dc-role-famous) !important; }
.r-serf   { color: var(--dc-role-serf) !important; }
.r-you    { color: var(--dc-role-serf) !important; font-weight: 700; }

/* the rules post quotes a custom emoji the server would render as an image */
.dc-emoji { font-style: normal; }
.msg p b { color: var(--dc-white); }
.mention { background: var(--dc-blurple-16); color: #c9cdfb; padding: 0 2px; }

/* -------------------------------------------------------------- the embeds */
.embed {
  display: flex;
  margin: 7px 0 0;
  max-width: 470px;
  background: var(--dc-slot-2);
  border-radius: 4px;
  overflow: hidden;
}
.embed .bar { flex: 0 0 4px; background: var(--dc-embed); }
.embed .body { padding: 9px 12px 10px; min-width: 0; }
.embed h3 { margin: 0; font-size: 15px; font-weight: 700; color: var(--dc-white); line-height: 1.3; }
.embed .sub { font-size: 13px; font-weight: 600; color: var(--dc-white); margin-bottom: 7px; }
.embed dl { margin: 0 0 7px; display: grid; gap: 0; }
.embed dl > div { display: flex; gap: 6px; }
.embed dt { color: var(--dc-text-4); }
.embed dd { margin: 0; color: var(--dc-white); }
.embed .cta { margin: 0; color: var(--dc-text-2); }
.embed .cta b { color: var(--dc-white); }
.embed .in { color: var(--dc-green); font-weight: 700; }
.embed .fixed { color: var(--dc-yellow); font-weight: 700; }
/* an entry that was refused: the store said no, and saying so in the
   same line the button sits under is the only place it will be read */
.embed .fail { color: var(--dc-red, #f2555a); font-weight: 700; }

/* the live/dummy badge in the channel header -- small, but it is the only
   thing on the page that distinguishes a stored entry from a pretend one */
.raffle-mode {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 3px;
  white-space: nowrap;
}
.raffle-mode.dummy { background: var(--dc-slot); color: var(--dc-mute); }
.raffle-mode.real  { background: #1e3a2a; color: var(--dc-green); }

.embed-actions { display: flex; gap: 7px; margin: 7px 0 0; flex-wrap: wrap; }
.dcbtn {
  appearance: none;
  border: 0;
  border-radius: 4px;
  background: var(--dc-btn);
  color: var(--dc-white);
  font: inherit;
  font-size: 12px;
  padding: 7px 13px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.dcbtn:hover { background: var(--dc-btn-hover); }
.dcbtn.pri { background: var(--dc-blurple); font-weight: 600; }
.dcbtn.pri:hover { background: var(--dc-blurple-hover); }
.dcbtn.done { background: var(--dc-go); }
.dcbtn.done:hover { background: var(--dc-go-hover); }
.dcbtn[disabled] { background: var(--dc-slot-off); color: var(--dc-mute-4); cursor: not-allowed; }
.dcbtn img { width: 15px; height: 15px; display: block; }

.dc-compose { flex: 0 0 auto; padding: 6px 12px 9px; }
.dc-compose > div {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  background: var(--dc-panel);
  border-radius: 7px;
  padding: 9px 13px;
  font-size: 11px;
  color: var(--dc-mute-2);
}
.dc-compose b { color: var(--dc-text-4); }

.dc-members { width: 152px; background: var(--dc-panel); padding: 12px 9px; overflow-y: auto; }

/* ------------------------------------------------------------ the scrollbars
   The three scrolling panes had no styling, so they got the operating
   system's own bar: a wide light-grey slab against a near-black panel, on top
   of a hand-drawn laptop. It read as a piece of Windows that had wandered in.

   Discord's own bar is the model: narrow, a dark track that belongs to the
   panel behind it, a thumb only a little lighter, and always present rather
   than fading in and out -- a bar that appears on hover makes the layout
   twitch as the mouse crosses it. */
.dc-msgs, .dc-chans, .dc-members {
  scrollbar-width: thin;                                   /* Firefox */
  scrollbar-color: var(--dc-slot-on) transparent;
  scrollbar-gutter: stable;      /* reserve the width, so text cannot reflow */
}
.dc-msgs::-webkit-scrollbar,
.dc-chans::-webkit-scrollbar,
.dc-members::-webkit-scrollbar { width: 8px; }

.dc-msgs::-webkit-scrollbar-track,
.dc-chans::-webkit-scrollbar-track,
.dc-members::-webkit-scrollbar-track { background: transparent; }

.dc-msgs::-webkit-scrollbar-thumb,
.dc-chans::-webkit-scrollbar-thumb,
.dc-members::-webkit-scrollbar-thumb {
  background: var(--dc-slot-on);
  border-radius: 4px;
  /* the border is transparent, so it reads as padding and the thumb sits
     inset from the edge the way Discord's does */
  border: 2px solid transparent;
  background-clip: padding-box;
}
.dc-msgs::-webkit-scrollbar-thumb:hover,
.dc-chans::-webkit-scrollbar-thumb:hover,
.dc-members::-webkit-scrollbar-thumb:hover { background: var(--dc-btn); background-clip: padding-box; }

/* Chrome draws arrow buttons at both ends on Windows. Discord has none. */
.dc-msgs::-webkit-scrollbar-button,
.dc-chans::-webkit-scrollbar-button,
.dc-members::-webkit-scrollbar-button { display: none; height: 0; }

.dc-msgs::-webkit-scrollbar-corner,
.dc-chans::-webkit-scrollbar-corner,
.dc-members::-webkit-scrollbar-corner { background: transparent; }
.dc-members h5 {
  margin: 12px 0 5px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--dc-mute-2);
}
.dc-members h5:first-child { margin-top: 0; }
.dc-members ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.dc-members li { display: flex; align-items: center; gap: 7px; min-width: 0; }
.dc-members .av { width: 32px; height: 32px; flex-basis: 32px; }
.dc-members .nm {
  font-size: 11px;
  color: var(--dc-mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dc-members li.you .nm { font-weight: 700; }

/* the client answers to the width of the glass, not the window, so a laptop
   shrunk on a wide screen drops its columns too */
@container (max-width: 700px) { .dc-members { display: none } }
@container (max-width: 580px) {
  /* .dc is the container, so a rule for .dc inside its own container query
     never applies -- that line was always dead. The columns follow the
     children now (see .dc above), so hiding one collapses its track. */
  .dc-side { display: none }

  /* The sidebar is the only other place the two raffle channels exist, so the
     tabs arrive in the SAME block that removes it. Splitting these across two
     breakpoints left a band -- container width 520 to 580, which is viewport
     600, 768 and 820 -- where neither existed and the channels could not be
     reached at all.
     `.dc-head .dc-tabs` rather than `.dc-tabs`: the base rule that hides them
     sits further down the file, and at equal specificity the later rule wins.
     One extra class makes this one win wherever either ends up. */
  .dc-head .dc-tabs { display: flex }

  .dc-rail { width: 46px; padding: 6px 0; gap: 5px }
  /* the header would otherwise name the channel twice */
  .dc-head > i, .dc-head > #chanName, .dc-head .topic { display: none }
  .dc-head { height: auto; padding: 6px 8px; gap: 5px }
  .dc-compose { padding: 7px 8px }
  /* the live/dummy badge is what tells a real entry from a rehearsal, so it
     gets a row of its own instead of being cut off */
  .dc-head .raffle-mode {
    flex: 1 0 100%;
    margin: 0;
    white-space: normal;
    font-size: 9.5px;
    line-height: 1.25;
  }
}

/* =============================================== 02/03 the phase table
   Reduced in width from the earlier build: the table is a list you read down
   a column, so it does not need a spread. */
.mint-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  gap: 3px;
  max-width: 780px;
  margin: 0 auto;
  /* the two panels are one instrument, so the shadow belongs to the pair
     rather than to each half -- the same hard offset every other surface
     on this page sits on */
  box-shadow: var(--shadow);
}
@media (max-width: 760px) { .mint-grid { grid-template-columns: minmax(0, 1fr) } }

.panel {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  padding: var(--s-lg);
  min-width: 0;
}
/* the two panels are one object and share a height, so the supply readout
   sits low in its column rather than leaving a hole under it -- but off the
   floor, and centred, because it is the headline number of the page */
.supply { margin-top: auto; margin-bottom: var(--s-lg); text-align: center; }
.panel::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border: 3px solid var(--b);
}

.panel-title {
  position: static;
  display: flex;
  justify-content: space-between;
  gap: var(--s-sm);
  margin: 0 0 var(--s-md);
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--a);
}
.panel-title span:last-child { color: var(--dimmer); }
/* the readout draws its own rule, in the pattern colour it already carries */
.panel-title::after {
  content: "";
  position: absolute;
  left: var(--s-lg);
  right: var(--s-lg);
  margin-top: calc(var(--s-md) * -1 + 4px);
  border-top: 1px solid var(--pat-16);
}

.phases { display: grid; gap: 3px; }
.phase {
  display: grid;
  /* three lines: what it is, when it runs, what it costs. The number stays in
     its own column so the four rows read as a numbered list. */
  grid-template-columns: 24px minmax(0, 1fr) auto;
  grid-template-areas:
    "no    nm    st"
    "blank when  when"
    "blank money money";
  gap: 2px var(--s-sm);
  align-items: center;
  padding: var(--s-sm) 0;
  border-bottom: 1px solid var(--edge);
}
.phase .no { grid-area: no; color: var(--dimmer); font-variant-numeric: tabular-nums; }
.phase .nm { grid-area: nm; color: var(--dim); min-width: 0; }
.phase .when {
  grid-area: when;
  display: block;
  margin-top: 0;
  font-weight: 400;
  font-size: var(--t-label-sm);
  letter-spacing: .08em;
  color: var(--dimmer);
  text-transform: none;
}
.phase.live .when { color: var(--dim); }

/* the info marker: how many wallets this phase can actually serve */
.info {
  display: inline-grid;
  place-items: center;
  width: 14px; height: 14px;
  margin-left: 7px;
  border: 1px solid var(--dimmer);
  border-radius: 50%;
  font-style: normal;
  font-size: 9px;
  line-height: 1;
  color: var(--dimmer);
  cursor: help;
  position: relative;
  vertical-align: baseline;
}
.info:hover, .info:focus { border-color: var(--a); color: var(--a); outline: none; }
.info .tip {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%);
  width: max-content;
  max-width: 220px;
  padding: 7px 10px;
  background: #000;
  border: 3px solid var(--a);
  color: var(--l);
  font-size: var(--t-label-sm);
  letter-spacing: .06em;
  text-transform: none;
  line-height: 1.5;
  opacity: 0;
  pointer-events: none;
  z-index: 5;
}
.info:hover .tip, .info:focus .tip { opacity: 1; }
.phase .pr { color: var(--dimmer); font-variant-numeric: tabular-nums; white-space: nowrap; }
.phase .money {
  grid-area: money;
  display: flex;
  gap: var(--s-md);
  align-items: baseline;
}
.phase .cap {
  color: var(--dimmer);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.phase.live .cap { color: var(--dim); }
.phase .st {
  grid-area: st;
  border: 3px solid var(--edge);
  padding: 3px 8px;
  color: var(--dimmer);
  white-space: nowrap;
}
/* The phase that is open is the one thing in this table anybody is looking
   for, so it is the only row that is filled rather than outlined. Everything
   else steps back to let it read. */
.phase.live {
  /* the accent bar the row is marked with, drawn in its own padding */
  box-shadow: inset 3px 0 0 var(--b);
  padding-left: var(--s-sm);
}
.phase.live .no { color: var(--b); }
.phase.live .nm { color: var(--l); font-weight: 600; }
.phase.live .pr { color: var(--l); }
.phase.done .nm { color: var(--dimmer); }
.phase.done .st { color: var(--dimmer); }
/* the phase this wallet is actually cleared for */
.phase.yours { border-color: var(--a); }
.phase.yours .nm { color: var(--l); font-weight: 600; }
.phase.yours .st { border-color: var(--a); color: var(--a); }

/* The open phase is the one row anybody is scanning for, so it is the only
   chip that is filled rather than outlined. It is stated last on purpose:
   a row can be both open and yours, and when it is, "open now" is the fact
   that matters -- and the fill has to bring its own text colour with it,
   because --a and --b are the same ink in two of the five colorways. */
.phase.live .st {
  border-color: var(--b);
  background: var(--b);
  color: var(--on-b, var(--ink));
  font-weight: 600;
}

.supply { padding-top: var(--s-md); }
.supply-num {
  font-family: var(--pixel);
  font-size: var(--t-display);
  font-weight: 400;
  color: var(--b);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  /* the brackets the page puts around anything it is quoting back at you */
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--s-sm);
}
.supply-num::before,
.supply-num::after {
  /* a frame, not a second voice: the number is what is being read */
  color: var(--dimmer);
  font-size: var(--t-figure);
}
.supply-num::before { content: "["; }
.supply-num::after  { content: "]"; }
.supply-num s { text-decoration: none; color: var(--dimmer); }
.supply-bar {
  height: 18px;
  margin: var(--s-sm) 0 var(--s-xs);
  background: rgba(0,0,0,.5);
  border: 3px solid var(--pat-16);
}
.supply-bar i {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--scan);
  /* It fills in steps, the way the rest of the work is drawn -- and it fills
     by transform rather than by width, so the growth costs no layout. */
  transform-origin: left center;
  transition: transform .4s steps(12, end);
}
.supply-pct {
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--dimmer);
}

/* the cost calculator: what this many, at this phase's price, actually costs.
   A buyer should never have to do the multiplication themselves. */
.cost {
  margin: var(--s-md) 0;
  border: 3px solid var(--edge);
  padding: var(--s-sm) 12px 12px;
}
.cost .row {
  display: flex;
  justify-content: space-between;
  gap: var(--s-sm);
  padding: 3px 0;
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--dimmer);
}
.cost .row b { color: var(--dim); font-weight: 400; font-variant-numeric: tabular-nums; }
.cost-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s-sm);
  margin-top: var(--s-sm);
  padding-top: var(--s-sm);
  border-top: 3px solid var(--edge);
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
}
.cost-total b {
  font-family: var(--pixel);
  font-size: var(--t-figure);
  font-weight: 400;
  color: var(--b);
  font-variant-numeric: tabular-nums;
}
.cost-note {
  margin: var(--s-sm) 0 0;
  font-size: var(--t-body-sm);
  line-height: 1.5;
  color: var(--dimmer);
}

.price-eth { padding-top: var(--s-xs); }
.price-eth small {
  display: block;
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--dimmer);
}
.price-eth span {
  display: block;
  font-family: var(--pixel);
  font-size: var(--t-headline);
  font-weight: 400;
  color: var(--b);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  margin-top: var(--s-xs);
}

.qty {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) 46px;
  margin: var(--s-md) 0 var(--s-sm);
  border: 3px solid var(--edge);
  height: 46px;
}
.qty button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--b);
  font-family: var(--pixel);
  font-size: var(--t-title);
  cursor: pointer;
  line-height: 1;
}
.qty button:hover:not(:disabled) { background: var(--b); color: var(--ink); }
/* At the limit the button has nothing to do, and it has to look that way.
   Without this the only signal was the number refusing to move, which reads
   as a broken control rather than a rule. */
.qty button:disabled {
  color: var(--edge);
  cursor: not-allowed;
  background: transparent;
}
.qty input:disabled { color: var(--edge); }
.qty-cap {
  margin: 0 0 var(--s-md);
  font-family: var(--mono, monospace);
  font-size: var(--t-body-sm);
  color: var(--dim);
  opacity: .75;
}
.qty-cap.none { opacity: 1; }

/* ------------------------------------------------- vault and recipient
   Two optional aims for a mint: whose allowance, and where the tokens land.
   Quieter than the stepper above them -- most people never touch either, and
   a field that shouts competes with the button that matters. */
.delegate {
  display: grid;
  gap: var(--s-md);
  margin: 0 0 var(--s-md);
  padding: var(--s-md) 0 0;
  border-top: 1px solid var(--edge);
}
.field { display: grid; gap: var(--s-xs); }
.field > span {
  font-family: var(--pixel);
  font-size: var(--t-label-sm);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
}
.field > span i {
  font-style: normal;
  color: var(--dimmer);
  margin-left: 6px;
}
.field input {
  background: transparent;
  border: 2px solid var(--edge);
  color: var(--l);
  font-family: var(--mono);
  font-size: var(--t-body-sm);
  padding: 9px 11px;
  min-width: 0;
}
.field input:focus-visible {
  outline: none;
  border-color: var(--b);
}
.field input::placeholder { color: var(--dimmer); }
.field-note {
  font-family: var(--mono);
  font-size: var(--t-label);
  color: var(--dim);
  line-height: 1.45;
}
.field-note.ok  { color: var(--scan); }
.field-note.bad { color: var(--a); }
.qty input {
  border: 0;
  border-left: 3px solid var(--edge);
  border-right: 3px solid var(--edge);
  background: transparent;
  color: var(--l);
  font-family: var(--pixel);
  font-size: var(--t-headline);
  font-weight: 400;
  text-align: center;
  min-width: 0;
  padding: 0;
  font-variant-numeric: tabular-nums;
}
.qty input:focus { outline: none; background: rgba(255,255,255,.05); }

.mint-note {
  margin: var(--s-sm) 0 0;
  font-size: var(--t-body-sm);
  line-height: 1.55;
  color: var(--dim);
}
.mint-note.good { color: var(--a); }
.mint-note.bad { color: var(--alarm); }
.status-line {
  margin: var(--s-md) 0 0;
  padding-top: var(--s-sm);
  border-top: 3px solid var(--edge);
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--dimmer);
}

.fineprint {
  max-width: 68ch;
  margin: var(--s-lg) auto 0;
  font-size: var(--t-body-sm);
  line-height: 1.7;
  color: var(--dimmer);
}
.fineprint a { color: var(--b); }

/* ============================================================== the notice
   The out-of-character block: this build is a design dummy and says so in the
   one colour the collection reserves for disclosure. */
.notice {
  max-width: 780px;
  margin: var(--s-lg) auto 0;
  padding: var(--s-md);
  background: rgba(48,42,6,.45);
  border: 3px solid var(--notice);
  font-size: var(--t-body-sm);
  line-height: 1.65;
  color: var(--l);
}
.notice b {
  display: block;
  margin-bottom: var(--s-xs);
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--notice);
}
.notice-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-sm) var(--s-lg);
  margin-top: var(--s-md);
  padding-top: var(--s-md);
  border-top: 3px solid rgba(245,242,60,.3);
}
.notice label { display: inline-flex; align-items: center; gap: var(--s-sm); flex-wrap: wrap; }
.notice .chip {
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--dimmer);
}
.notice .chip b { color: var(--l); font-weight: 400; text-transform: none; letter-spacing: .04em; }

/* the stage switcher, a review control */
.stagepick { display: flex; align-items: center; }
.stagepick > i {
  font-style: normal;
  padding-right: var(--s-sm);
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--dimmer);
}
.stagepick button {
  appearance: none;
  border: 3px solid rgba(245,242,60,.4);
  border-left-width: 0;
  background: transparent;
  color: var(--dim);
  font-family: var(--pixel);
  font-size: var(--t-nav);
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1;
  padding: 9px 12px;
  cursor: pointer;
}
.stagepick button:first-of-type { border-left-width: 3px; }
.stagepick button:hover { color: #000; background: var(--notice); border-color: var(--notice); }
.stagepick button[aria-pressed="true"] { color: var(--notice); border-color: var(--notice); }
.stagepick button:focus-visible { outline: 3px solid var(--a); outline-offset: 2px; }
.notice select {
  font-family: var(--mono);
  font-size: var(--t-body-sm);
  background: var(--ink);
  color: var(--l);
  border: 3px solid var(--notice);
  padding: 7px 9px;
  cursor: pointer;
}
.notice select:focus-visible { outline: 3px solid var(--a); outline-offset: 2px; }

/* ================================================================ the modal
   The eligibility result: the payoff of the whole flow, so it gets the
   display face and the accent rule, and the celebration runs behind it. */
.modal {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: var(--s-lg);
  background: rgba(0,0,0,.8);
}
.modal[hidden] { display: none; }
.modal-card {
  position: relative;
  z-index: 2;
  width: min(580px, 100%);
  max-height: 86vh;
  overflow-y: auto;
  padding: var(--s-xl);
  background: #000;
  border: 3px solid var(--b);
  box-shadow: var(--shadow);
}
@media (prefers-reduced-motion: no-preference) {
  .modal-card { animation: cardin .18s steps(3) both; }
  @keyframes cardin { from { transform: translate(-6px, -6px) } }
}
.modal-card.sad { border-color: var(--dim); }

.modal-card h2 {
  margin: 0 0 var(--s-md);
  font-family: var(--pixel);
  font-size: var(--t-display);
  font-weight: 400;
  letter-spacing: .01em;
  line-height: 1.15;
  color: var(--b);
  text-wrap: balance;
}
.modal-card.sad h2 { color: var(--dim); }
.modal-card .said {
  margin: 0;
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--l);
}
.modal-card .said b { color: var(--b); }
.modal-card.sad .said b { color: var(--l); }

.grants { list-style: none; margin: var(--s-lg) 0 0; padding: 0; display: grid; gap: 3px; }
.grants li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-sm);
  padding: 12px 13px;
  background: rgba(0,0,0,.4);
  border: 3px solid var(--edge);
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .12em;
  text-transform: uppercase;
}
.grants li.on { border-color: var(--a); }
.grants .k { color: var(--dim); }
.grants li.on .k { color: var(--l); }
.grants .v { color: var(--a); font-weight: 600; white-space: nowrap; }
.grants li.off .k { color: var(--dimmer); }
.grants li.off .v { color: var(--dimmer); font-weight: 400; }

.modal-actions { display: flex; flex-wrap: wrap; gap: var(--s-sm); margin: var(--s-lg) 0 0; }
.modal-actions .btn { flex: 1 1 auto; padding: 15px 22px; }
.modal-actions .btn.ghost { padding: 12px 19px; }
.modal-close {
  position: absolute;
  top: 6px; right: 8px;
  z-index: 3;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--dimmer);
  font-family: var(--pixel);
  font-size: var(--t-headline);
  line-height: 1;
  padding: var(--s-sm) 12px;
  cursor: pointer;
}
.modal-close:hover { color: var(--b); }
.modal-close:focus-visible { outline: 3px solid var(--a); outline-offset: 0; }

/* The celebration: a canvas, so a hundred falling emoji cost nothing. It sits
   inside the modal, in front of the backdrop and behind the card — confetti
   raining over the sentence you are trying to read is a cost with no return. */
#rain { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
#rain[hidden] { display: none; }

/* ------------------------------------------------------------------- footer */
/* The page is a column the height of the window, so the footer lands on the
   floor even when a stage is short, rather than floating under the content
   with a lake of empty page below it. */
.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
.page > main, .page > .gallery { flex: 1 0 auto; }
.page > .foot { margin-top: auto; }

.foot {
  margin: var(--s-section) 0 0;
  padding-top: var(--s-md);
  border-top: 3px solid var(--edge);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-sm) var(--s-lg);
  align-items: center;
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--dimmer);
}
.foot .push { margin-left: auto; }
.foot a { color: var(--dim); text-decoration: none; }
.foot a:hover { color: var(--b); }

/* ================================================================== the gate
   The first thing the page says, because it is the thing that most needs
   saying: this is a derivative, and nobody blessed it. Carried over from
   V0.2, in the colour the collection keeps for disclosure. */
.gate {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: var(--s-lg);
  background: rgba(0,0,0,.9);
  overflow-y: auto;
}
.gatebox {
  max-width: 620px;
  width: 100%;
  background: var(--ink);
  border: 3px solid var(--notice);
  padding: var(--s-xl) var(--s-lg) var(--s-lg);
  box-shadow: 10px 10px 0 rgba(0,0,0,.6);
}
.gatebox .kick {
  display: block;
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--notice);
  margin-bottom: var(--s-md);
}
.gatebox h2 {
  margin: 0 0 var(--s-md);
  font-family: var(--pixel);
  font-size: var(--t-display-page);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: .01em;
  text-transform: uppercase;
  color: var(--l);
  text-wrap: balance;
}
.gatebox h2 b { color: var(--notice); }
.gatebox p { margin: 0 0 var(--s-sm); color: var(--dim); font-size: var(--t-body); }
.gatebox p b { color: var(--l); }
.gateBtn {
  margin-top: var(--s-lg);
  width: 100%;
  padding: 18px;
  border: 0;
  cursor: pointer;
  background: var(--notice);
  color: #000;
  font-family: var(--pixel);
  font-size: var(--t-title);
  letter-spacing: .06em;
  text-transform: uppercase;
  box-shadow: var(--shadow);
}
.gateBtn:hover { background: var(--l); }
.gateBtn:active { transform: translate(2px, 2px); box-shadow: var(--shadow-in); }
.gateBtn:focus-visible { outline: 3px solid var(--l); outline-offset: 3px; }

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--a);
  color: var(--ink);
  padding: var(--s-sm) var(--s-md);
  z-index: 100;
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.skip:focus { left: var(--s-lg); }


/* =========================================================== what you minted
   The result of a mint, as an object you can look at: the face, its number,
   the colorway it came out in, and a way to page through a stack of them. */
.mint-card { max-width: 460px; text-align: center; }
.mint-shot { margin: var(--s-lg) 0; }
.mint-frame { max-width: 300px; margin: 0 auto; }
.mint-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: var(--s-md);
}
.mint-meta b {
  font-family: var(--pixel);
  font-size: var(--t-h3);
  color: var(--a);
  letter-spacing: .04em;
}
.mint-meta span { font-size: var(--t-sm); color: var(--dim); }

.mint-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-md);
  margin-top: var(--s-md);
}
.navbtn {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  background: var(--ink);
  border: 3px solid var(--edge);
  color: var(--l);
  font-size: 15px;
  cursor: pointer;
}
.navbtn:hover { border-color: var(--a); color: var(--a); }
.navbtn:active { transform: translate(2px, 2px); }
.navbtn:focus-visible { outline: 3px solid var(--b); outline-offset: 2px; }
.mint-count {
  font-family: var(--pixel);
  font-size: var(--t-sm);
  color: var(--dim);
  min-width: 56px;
  font-variant-numeric: tabular-nums;
}


/* The eye on the lid blinks now and again -- the machine is watching, and a
   thing that watches should look alive. It is the pupil that goes, not the
   whole eye: the lid stays drawn. */
/* The blink is an eyelid now, not the pupil flickering out.
   The lid rests one eye-height above the eye, clipped to the eye shape, so at
   translateY(0) it is invisible. Dropping it by a little more than the eye's
   height covers the eye completely; coming back up opens it.

   Held open for most of the cycle and shut briefly, which is what a blink is.
   The transform is in user units because that is what a transform on an SVG
   element means -- percentages would resolve against the wrong box. */
@keyframes eyelid {
  0%, 90%   { transform: translateY(0) }
  94%, 95%  { transform: translateY(var(--lid, 56px)) }
  99%, 100% { transform: translateY(0) }
}
.laptop-art .eyelid { animation: eyelid 6s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  /* parked open, not parked shut */
  .laptop-art .eyelid { animation: none; transform: translateY(0) }
}


/* ============================================================= the wallet chip
   A connected wallet, shown the way a dapp shows one: an address you can click
   and the two things anyone actually wants behind it. */
.wallet-tag { position: absolute; top: 0; right: 0; z-index: 30; text-align: right; }
.wallet-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 11px;
  background: var(--ink);
  border: 3px solid var(--edge);
  color: var(--l);
  font-family: var(--pixel);
  font-size: var(--t-nav);
  letter-spacing: .04em;
  cursor: pointer;
}
.wallet-btn:hover { border-color: var(--a); color: var(--a); }
.wallet-btn:focus-visible { outline: 3px solid var(--b); outline-offset: 2px; }
.wallet-btn .dot {
  width: 7px; height: 7px;
  background: var(--go);
  box-shadow: 0 0 6px var(--go);
}
.wallet-menu {
  position: absolute;
  right: 0;
  margin-top: 4px;
  min-width: 210px;
  background: var(--ink);
  border: 3px solid var(--a);
  box-shadow: var(--shadow);
  text-align: left;
}
.wallet-full {
  margin: 0;
  padding: 9px 11px;
  border-bottom: 1px solid var(--edge);
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  color: var(--dim);
  word-break: break-all;
}
.wallet-item {
  display: block;
  width: 100%;
  padding: 9px 11px;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--edge);
  color: var(--l);
  font-family: var(--pixel);
  font-size: var(--t-nav);
  letter-spacing: .04em;
  text-align: left;
  cursor: pointer;
}
.wallet-item:last-child { border-bottom: 0; }
.wallet-item:hover { background: var(--a); color: var(--ink); }
.wallet-item:focus-visible { outline: 3px solid var(--b); outline-offset: -3px; }
@media (max-width: 620px) {
  .wallet-tag { position: static; margin-bottom: var(--s-md); text-align: center; }
  .wallet-menu { position: static; margin: 4px auto 0; }
}

/* ================================================================ the gallery
   What the wallet holds, with both files made on demand rather than stored. */
.gallery { padding: var(--s-xl) 0 var(--s-2xl); }
/* title on the left, the way out on the right where a done control belongs */
.gallery-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-md);
  margin-bottom: var(--s-xl);
}
.gallery-head h2 {
  margin: 0;
  font-family: var(--pixel);
  font-size: var(--t-h2);
  color: var(--a);
  letter-spacing: .06em;
  text-transform: uppercase;
}
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--s-lg);
}
.own { margin: 0; }
.own .frame { width: 100%; cursor: default; }
.own .frame:active { transform: none; box-shadow: var(--shadow); }
.own figcaption {
  margin-top: var(--s-sm);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.own figcaption b {
  font-family: var(--pixel);
  font-size: var(--t-sm);
  color: var(--a);
  letter-spacing: .04em;
}
.own figcaption span { font-size: var(--t-label-sm); color: var(--dimmer); }
.own-actions { display: flex; gap: var(--s-xs); margin-top: var(--s-xs); }
.minibtn {
  padding: 5px 10px;
  background: var(--ink);
  border: 3px solid var(--edge);
  color: var(--dim);
  font-family: var(--pixel);
  font-size: var(--t-label-sm);
  letter-spacing: .06em;
  cursor: pointer;
}
.minibtn:hover:not(:disabled) { border-color: var(--a); color: var(--a); }
.minibtn:active:not(:disabled) { transform: translate(2px, 2px); }
.minibtn:disabled { opacity: .55; cursor: wait; }
.minibtn:focus-visible { outline: 3px solid var(--b); outline-offset: 2px; }

/* ======================================================== the live-mode switch
   Only shown when a chain-config.json is sitting next to the page. It lives in
   the review panel with the other things that come out before launch. */
.live-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--s-xs);
  cursor: pointer;
}
.live-switch b { color: var(--scan); }
.chain-found {
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  color: var(--dim);
}

/* The badge is never absent: a page that talks to a chain and a page that only
   pretends to must never be mistaken for one another. */
.chain-badge {
  margin: var(--s-lg) 0 0;
  padding: var(--s-xs) var(--s-sm);
  border: 1px solid var(--edge);
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--dimmer);
  text-align: center;
}
.chain-badge.live {
  border-color: var(--scan);
  color: var(--scan);
}
.chain-badge a { color: inherit; }

/* =========================================================== the narrow view
   A laptop on a phone was a laptop nobody could read: below 720px the machine
   was hidden altogether and the chat client became a plain box, which threw
   away the artwork and still left the client too cramped to use.

   Instead the laptop is ZOOMED. It is made wider than the viewport and pulled
   left so the screen fills the width, with about 5px of the machine's edge
   still showing on each side -- it stays a laptop, and the screen gets the
   room.

   The two numbers come from the trace (laptop-art.js), not from trying values:

     the screen starts at 13.372% of the machine's width
     and is    67.818% of it wide

   So to make the screen (V - 10px) wide inside a stage of width V:
       L = (V - 10px) / 0.67818        = (V - 10px) x 1.47453
   and to put its left edge 5px in from the stage's left:
       margin-left = 5px - 0.13372 x L = 5px - (V - 10px) x 0.19717

   Percentages in width and margin-left both resolve against the stage, so the
   two stay in step at any width. */
.laptop-stage { position: relative; }

@media (max-width: 720px) {
  .laptop-stage { overflow: hidden; }
  .laptop-stage .laptop {
    width: calc((100% - 10px) * 1.47453);
    max-width: none;
    margin-left: calc(5px - (100% - 10px) * 0.19717);
    margin-right: 0;
  }
  /* The art stays. It was display:none here, which is what made the page stop
     being the artwork at exactly the width where most people see it. */
  .laptop-art { display: block; }
  .laptop .screen {
    position: absolute;
    border: 0;
    outline: 3px solid var(--a);
  }
  /* The trackpad key keeps its label on a phone too: it is drawn on the
     machine, and hiding it left the keyboard with a blank key. */
  .deck-back { display: flex; }
}

/* ---------------------------------------------------------- the channel tabs
   ALWAYS shown, at every width.
   The first version only showed them once the sidebar was hidden, on the
   reasoning that two copies of one control is one too many. That was wrong in
   practice: the two raffle channels sit at the bottom of the sidebar behind
   three categories and six other channels, so on any screen that is short --
   and inside a laptop drawing, most of them are -- they fall below the fold of
   a panel that scrolls inside a picture. Reachable in theory, unreachable in
   fact.
   These are the two controls the page exists for. They get a place that does
   not depend on the height of anything, and they keep it at every size.
   They carry .dc-chan[data-chan], so showChannel() marks the open one in both
   places at once. */
.dc-tabs {
  /* Off by default: above the breakpoint the sidebar lists both channels and
     a second copy in the header would be clutter. Switched on in the same
     block that removes the sidebar, so the two can never disagree -- they did
     once, at two different breakpoints, and between 520 and 580 neither
     existed. */
  display: none;
  width: 100%;
  gap: 6px;
  align-items: center;
  order: -1;            /* first in the header, before the channel name */
}

.dc-tab {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 6px 6px;
  border: 1px solid var(--dc-line-2);
  border-radius: 5px;
  background: transparent;
  color: var(--dc-mute);
  font: inherit;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dc-tab i { font-style: normal; opacity: .6; }
.dc-tab:hover { background: var(--dc-slot); color: var(--dc-text); }
/* The open one is marked twice over -- filled and outlined -- because on a
   phone in daylight a colour shift on its own is not a difference anyone
   sees. */
.dc-tab.on {
  background: var(--dc-slot-on);
  color: var(--dc-white);
  border-color: var(--dc-mute-3);
  font-weight: 700;
}
.dc-tab .badge {
  flex: 0 0 auto;
  min-width: 15px;
  height: 15px;
  padding: 0 4px;
  border-radius: 8px;
  background: var(--dc-brand);
  color: var(--dc-white);
  font-size: 9px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ------------------------------------------------------------ room to breathe
   The footer used to start immediately under the last line of text, so the
   page ended without a pause. */
.foot { margin-top: var(--s-section); }
main > .cta-row:last-of-type { margin-bottom: var(--s-xl); }
.drop { margin-bottom: var(--s-xl); }
