/* ============================================================
   PUNKAGENTS-MAIN.CSS
   Single consolidated stylesheet. Replaces both
   Bootstrap-CPOLore1155-4.4.1.css and PunkAgents-Styles.css.
   Includes minimal Bootstrap-compatible navbar + container
   rules so we no longer depend on the Bootstrap stylesheet.
   The Bootstrap-4 JavaScript (hamburger toggle) still works
   because it only touches `.show` / `.collapsed` classes.
   ============================================================ */

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



/* ⚠️ GLOBAL SAFETY NET — LEAVE THIS NEAR THE TOP, AND DO NOT NARROW IT.
   The `hidden` attribute is nothing more than a UA rule of `display: none`, so ANY rule that sets
   `display` on the same element silently defeats it: the JS sets `hidden = true`, the element stays on
   screen, and nothing in the JS hints at why. That has happened FOUR separate times in this project —
   #csStartingImagesNote, #csChangeStep2Label, the poster export buttons showing in Share mode, and the
   coupon issuer's CONNECT button, each kept visible by a `display` rule written for an unrelated reason
   (centring, layout, a flex container). Every one was diagnosed as a JS bug first.
   This makes `hidden` win, so the next `display` rule cannot bring the problem back. The per-element
   `[hidden]` rules further down are now redundant; they are left in place because each records the
   specific trap it was written for. */
[hidden] { display: none !important; }

html,
body {
   margin: 0;
   padding: 0;
}

body {
   background-color: #0a0a1a;
   color: #e3e3e3;
   font-family: 'Chakra Petch', 'Helvetica Neue', Arial, sans-serif;
   line-height: 1.5;
}

a {
   color: inherit;
   text-decoration: none;
}

img {
   vertical-align: middle;
   border-style: none;
}

button {
   cursor: pointer;
   font-family: inherit;
}


/* ============================================================
   .container (Bootstrap-compatible)
   ============================================================ */
.container {
   width: 100%;
   padding-right: 15px;
   padding-left: 15px;
   margin-right: auto;
   margin-left: auto;
}

@media (min-width: 576px)  { .container { max-width: 540px; } }
@media (min-width: 768px)  { .container { max-width: 766px; } }
@media (min-width: 992px)  { .container { max-width: 960px; } }
@media (min-width: 1200px) { .container { max-width: 1140px; } }


/* ============================================================
   NAVBAR (replicates the Bootstrap-4 classes we actually use)
   ============================================================ */
.navbar {
   min-height: 80px;
   width: 100%;
   position: relative;
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   justify-content: space-between;
   padding: 0.5rem 1rem;
}

.navbar.py-3 {
   padding-top: 1rem;
   padding-bottom: 1rem;
}

.navbar > .container {
   display: flex;
   flex-wrap: inherit;
   align-items: center;
   justify-content: space-between;
}

.bg-dark {
   background-color: #343a40 !important;
}

.shadow-sm {
   box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;
}

.navbar-toggler {
   /* ⚠️ KEEPS THE HAMBURGER ON THE RIGHT. `.navbar > .container` is a flex row with `flex-wrap: wrap`
      and `justify-content: space-between`. On a narrow screen the logo can fill the first row, which
      wraps the button onto a row of its own — and space-between puts a LONE item at the START, so the
      button jumped to the far LEFT. `margin-left: auto` pins it right whether it wraps or not.
      Do not "simplify" this away: it looks redundant while the row fits, and only shows when it does not. */
   margin-left: auto;
   padding: 0.25rem 0.75rem;
   font-size: 1.25rem;
   line-height: 1;
   background-color: transparent;
   border: 1px solid rgba(255, 255, 255, 0.1);
   border-radius: 0.25rem;
   color: #fff;
}

.navbar-toggler-icon {
   display: inline-block;
   width: 1.5em;
   height: 1.5em;
   vertical-align: middle;
   background: 50% / 100% 100% no-repeat;
   background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba%28255, 255, 255, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");
}

.navbar-collapse {
   flex-basis: 100%;
   flex-grow: 1;
   align-items: center;
}

.collapse:not(.show) {
   display: none;
}

.navbar-nav {
   display: flex;
   flex-direction: column;
   padding-left: 0;
   margin-bottom: 0;
   list-style: none;
}

.ml-auto {
   margin-left: auto !important;
}

.nav-item {
   list-style: none;
   border-bottom: solid 1px gray;
}

.nav-item:last-child {
   border-bottom: none;
}



/* TWO LINKS, ONE ROW SLOT — the FAQ / FAQ-PUBLIC pair sits one ON TOP OF the other.
   WHY: #PunkRevolutionsLogoDIV is absolutely centred over the bar (see the <style> block in
   revolutionsMinter.html), so it does NOT push the link row aside — once the row grew wide enough to
   reach the middle, adding EDITIONS slid the links UNDER the logo and hid them. Stacking the two FAQ
   links halves what they cost horizontally instead of shrinking the logo or the type.
   On phones the navbar-nav is already a column, so this changes nothing there. */
.nav-item-stack {
   display: flex;
   flex-direction: column;
   justify-content: center;
}

.nav-link {
   display: block;
   padding: 0.5rem 1rem;
   color: rgba(255, 255, 255, 0.85);
   text-decoration: none;
}

.nav-link:hover {
   color: #fff;
}

/* Desktop uses the same collapsed menu as mobile; keep the theme switch beside the hamburger. */
@media (min-width: 992px) {
   nav.navbar .switch { margin-left: auto; margin-right: 12px; }
   nav.navbar .navbar-toggler { margin-left: 0; }
}

/* Project-specific navbar overrides */
.navbar-dark .navbar-nav .nav-link {
   color: #cdeeff;
   font-weight: 600;
   letter-spacing: 0.5px;
}

.navbar-dark .navbar-nav .nav-link:hover {
   color: #00ffcc;
}

#PunkRevolutionsLogoDIV {
   color: #00ffcc;
   font-weight: 700;
   font-size: 2.75rem;
   letter-spacing: 1px;
   text-shadow: 0 0 8px rgba(0, 255, 204, 0.4);
   padding: 4px 0;
   white-space: nowrap;   /* keep "PUNK <word>" on ONE line (was wrapping to two on phones) */
}

.navbar > .container > a {
   padding: 0;
}


/* ============================================================
   WALLET ICON + INFO BAR
   ============================================================ */
#walletIconLink {
   position: relative;
   padding-right: 24px !important;
}

#walletIconLink img {
   width: 60px;
   height: auto;
   margin-top: -3px;
   filter: sepia(100%) saturate(5000%) hue-rotate(-50deg) brightness(0.85);
   transition: filter 0.3s ease;
}

#walletIconLink:hover img {
   filter: drop-shadow(0 0 8px rgba(57, 199, 255, 0.95));
}

#walletIconLink.connected img {
   filter: sepia(1) saturate(3) hue-rotate(160deg) brightness(1.1) drop-shadow(0 0 10px rgba(57, 199, 255, 0.95));
}

#walletIconLink.connected:hover img {
   filter: sepia(1) saturate(3) hue-rotate(160deg) brightness(1.2) drop-shadow(0 0 15px rgba(57, 199, 255, 1));
}

#walletCheckmark {
   display: none;
   position: absolute;
   top: 3px;
   right: 10px;
   width: 18px;
   height: 18px;
   background: rgb(0, 150, 255);
   color: #fff;
   font-size: 12px;
   font-weight: bold;
   line-height: 18px;
   text-align: center;
   border-radius: 50%;
   box-shadow: 0 0 6px rgba(0, 150, 255, 0.8);
}

#walletIconLink.connected #walletCheckmark {
   display: block;
}

#walletXmark {
   display: block;
   position: absolute;
   top: 3px;
   right: 10px;
   width: 18px;
   height: 18px;
   background: rgba(255, 60, 60, 0.85);
   color: #fff;
   font-size: 12px;
   font-weight: bold;
   line-height: 18px;
   text-align: center;
   border-radius: 50%;
}

#walletIconLink.connected #walletXmark {
   display: none;
}

#walletInfoWrapperDIV {
   /* 🚨 `position: relative` IS WHAT MAKES #walletRolesPanel LAND UNDER THE BAR. The panel is
      `position: absolute; top: 100%`, and absolute positioning resolves against the nearest POSITIONED
      ancestor — with none, that is the initial containing block, so `top: 100%` meant 100% of the whole
      PAGE's height and the panel opened right at the bottom of the document. Measured: you had to scroll
      to the end of the page to find it. Nothing else is affected: `.switch`, which minterTheme.js moves
      in here on mobile, is already `position: relative`, so its own absolute children still resolve
      against it. */
   position: relative;
   width: 100%;
   height: 30px;
   background-color: #092b56;
   border-top: solid 1px gray;
   color: white;
   font-size: 0.84rem;
}

#walletInfoDIV {
   width: 100%;
   margin: 0 auto;
   padding: 5px 12px;
   text-align: center;
}

#connectedWalletLabel,
#connectedBlockchainNetworkLabel {
   color: rgba(57, 199, 255, 0.8);
}

#connectedWalletLabel {
   margin-right: 15px;
}

/* NO WALLET CONNECTED — the one state on this bar worth shouting about.
   ⚠️ A CLASS, NOT A COLOUR WRITTEN FROM JS. walletConnect.js adds and removes `notConnected`; the
   appearance is here, which is the only way the light-mode pair below can ever apply (an inline style
   outranks every selector — the mistake that left #editionsStatusDIV's daylight rule dead for months).
   ⚠️ IT ALSO BEATS THE BASE RULE ABOVE because id+class is more specific than id alone — no
   !important needed, and none should be added. */
#connectedWalletLabel.notConnected {
   color: #ff4d5e;
   font-weight: 700;
}




/* CONNECT WALLET — the desktop bar's own way out of "not connected".
   ⚠️ DESKTOP ONLY, BECAUSE THE MOBILE ROUTE ALREADY EXISTS. Below 992px the hamburger is on screen and
   its wallet icon does the same job; the bar there is a single cramped line that this would crowd. Hidden
   in the ≤991.98px block further down — NOT here — so the two rules read in breakpoint order.
   ⚠️ ITS VISIBILITY IS THE `hidden` ATTRIBUTE, set by updateWalletUI(). That composes with the media
   query; an inline `style.display` from JS would beat it and put the button back on phones. */
#walletConnectButton {
   margin-left: 14px;
   margin-bottom: 0px;
   padding: 2px 10px 2px 10px;
   min-width: 0;
   width: auto;
   font-size: 0.74rem;
   font-weight: 700;
   line-height: 1.5;
   letter-spacing: 0.5px;
   background: #1df07c;
   color: #0070ff;
   /* color: #ffffff; */
   /* background: #0070ff; */

   border: 1px solid #2b6cff;
   border-radius: 4px;
   cursor: pointer;
   vertical-align: middle;
}




#walletConnectButton:hover {
   /* background: #1550d8; */
   color: magenta;
   border-color: magenta;
}


body.daytime #walletConnectButton:hover {
   /* background: #1550d8; */
   color: magenta;
   border-color: magenta;
}


body.daytime #walletConnectButton {
   color: #0070ff;
   background: #1df07c;
   border-color: #1558d6;
}

@media (max-width: 575px) {
   #walletInfoWrapperDIV { font-size: 0.72rem; }
}


/* ===================== RESPONSIVE / MOBILE =====================
   ⚠️ THIS SECTION NOW LIVES AT THE VERY END OF THIS FILE. It used to sit here, in the middle, and
   that silently broke any override whose BASE rule was declared further down: same specificity (one
   id each), so the later rule won and the media query lost. #myEditionsDIV (base at ~line 878) and
   #mintCardDIV (base at ~line 585) were both affected — their mobile rules showed greyed-out in the
   inspector and never applied. Moved to the bottom so it wins by position, whatever gets added above.
   KEEP IT LAST. ===================== */





/* ============================================================
   WALLET MODAL
   ============================================================ */
#walletModal {
   display: none;
   position: fixed;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   background: rgba(0, 0, 0, 0.8);
   z-index: 2000;
   justify-content: center;
   align-items: center;
}

#walletModalContent {
   background: rgba(0, 20, 40, 0.95);
   border: 1px solid rgba(0, 255, 255, 0.3);
   border-radius: 16px;
   padding: 30px;
   max-width: 380px;
   width: 90%;
   backdrop-filter: blur(10px);
   box-shadow: 0 0 40px rgba(0, 255, 255, 0.2);
}

#walletModalContent h3 {
   color: #00ffff;
   font-size: 1.45rem;
   margin: 0 0 20px 0;
   text-align: center;
   text-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
}

.wallet-option {
   width: 100%;
   padding: 16px 20px;
   margin: 10px 0;
   background: rgba(0, 255, 255, 0.1);
   border: 1px solid rgba(0, 255, 255, 0.3);
   border-radius: 12px;
   color: #fff;
   font-size: 1.25rem;
   display: flex;
   align-items: center;
   gap: 12px;
   transition: all 0.2s;
}

.wallet-option:hover:not(:disabled) {
   background: rgba(0, 255, 255, 0.2);
   border-color: rgba(0, 255, 255, 0.6);
   box-shadow: 0 0 20px rgba(0, 255, 255, 0.3);
}

.wallet-option .wallet-icon {
   font-size: 1.25rem;
}

#closeWalletModal {
   width: 100%;
   padding: 12px;
   margin-top: 15px;
   background: transparent;
   border: 1px solid rgba(255, 255, 255, 0.2);
   border-radius: 8px;
   color: rgba(255, 255, 255, 0.6);
   font-size: 0.9rem;
   transition: all 0.2s;
}

#closeWalletModal:hover {
   border-color: rgba(255, 255, 255, 0.4);
   color: rgba(255, 255, 255, 0.9);
}


/* ============================================================
   SPINNER MODAL
   ============================================================ */
#spinnerModal {
   display: none;
   position: fixed;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   background: rgba(0, 0, 0, 0.85);
   z-index: 20000;
   justify-content: center;
   align-items: center;
}

#spinnerModalContent {
   background: rgba(0, 20, 40, 0.95);
   border: 1px solid rgba(0, 200, 255, 0.4);
   border-radius: 16px;
   padding: 40px;
   max-width: 350px;
   width: 90%;
   text-align: center;
   backdrop-filter: blur(10px);
   box-shadow: 0 0 40px rgba(0, 200, 255, 0.3);
}

.spinner {
   width: 60px;
   height: 60px;
   margin: 0 auto 20px auto;
   border: 4px solid rgba(0, 200, 255, 0.2);
   border-top: 4px solid rgb(0, 200, 255);
   border-radius: 50%;
   animation: spin 1s linear infinite;
}

@keyframes spin {
   0%   { transform: rotate(0deg); }
   100% { transform: rotate(360deg); }
}

#spinnerStatusText {
   color: rgb(0, 200, 255);
   font-size: 1.05rem;
}

/* Custom message dialog — replaces alert() in the mint flow. Success (default) = cyan; .is-error = red. */
#appMessageModal {
   display: none;
   position: fixed;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   background: rgba(0, 0, 0, 0.85);
   z-index: 20001;
   justify-content: center;
   align-items: center;
}

#appMessageModalContent {
   background: rgba(0, 20, 40, 0.97);
   border: 1px solid rgba(0, 255, 204, 0.5);
   border-radius: 16px;
   padding: 32px 34px;
   max-width: 440px;
   width: 90%;
   text-align: center;
   box-shadow: 0 0 44px rgba(0, 255, 204, 0.3);
}

#appMessageModalContent.is-error {
   border-color: rgba(255, 90, 120, 0.55);
   box-shadow: 0 0 44px rgba(255, 90, 120, 0.28);
}

#appMessageText {
   color: #d8fff6;
   font-size: 1.08rem;
   line-height: 1.5;
   white-space: pre-line; /* Preserve message newlines while allowing normal text wrapping. */
   margin-bottom: 22px;
   word-break: break-word;
}

#appMessageOkButton {
   background: #00ffcc;
   color: #05202a;
   border: none;
   border-radius: 8px;
   padding: 10px 34px;
   font-weight: 700;
   font-size: 1rem;
   cursor: pointer;
}

#appMessageModalContent.is-error #appMessageOkButton {
   background: #ff5a78;
   color: #ffffff;
}


/* ============================================================
   HERO
   ============================================================ */
#mainHeader {
   font-weight: 700;
   font-size: 2.2rem;
   color: #00ffcc;
   text-align: center;
   margin-top: 30px;
   text-shadow: 0 0 12px rgba(0, 255, 204, 0.4);
   letter-spacing: 1px;
}

#mainSubHeader {
   font-style: italic;
   color: #cdeeff;
   text-align: center;
   margin-top: 8px;
   margin-bottom: 30px;
}


/* ============================================================
   MINT CARD  (the styles that the user confirmed working)
   ============================================================ */
/* The three routes, stated at the top of the mint card before anything is asked for. */
#mintOptionsDIV {
   margin: 0px auto 18px auto;
   max-width: 560px;
   /* padding: 14px 16px; */
   /* background: rgba(43, 108, 255, 0.07); */
   /* border: 1px solid #2b6cff; */
   border-radius: 7px;
   text-align: left;
}



#mintOptionsDIV .mintOptionsHeader {
   margin-bottom: 8px;
   color: #7fb0ff;
   font-size: 0.95rem;
   font-weight: 700;
   text-align: center;
}



/* One framed block per route: the button, then what choosing it means. */
.mintOptionButtonDIV {
   background-color: #fff5e8;
   margin: 10px 0 0 0;
   padding: 12px 14px;
   border: 1px solid gray;
   border-radius: 7px;
   text-align: center;

   font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
}



/* ===================== WHAT THIS WALLET HAS ALREADY PAID FOR =====================
   Deliberately quieter than the mint grids: it is a receipt, not an offer. The one loud thing is a row
   this wallet can act on, which `.prepaidCellReady` marks. */
#myPrepaidDIV {
   max-width: 620px;
   margin: 0px auto 14px auto;
   padding: 23px 18px;
   border: 1px solid #2b6cff;
   border-radius: 9px;
   background: rgba(43, 108, 255, 0.07);
   text-align: center;
}




#myPrepaidHeading {
   margin: 0 0 6px;
   color: #7fb0ff;
   font-family: Arial, Helvetica, sans-serif;
   font-size: 1.3rem;
   font-weight: 600;
}




body.daytime #myPrepaidHeading { color: #1b4fa8; }




#myPrepaidSubheading {
   margin-bottom: 12px;
   color: #9fc4e8;
   font-size: 1.0rem;
   line-height: 1.5;
}




body.daytime #myPrepaidSubheading { color: #2f4b6b; }




#myPrepaidGrid {
   display: flex;
   flex-wrap: wrap;
   gap: 12px;
   justify-content: center;
}




.prepaidCell {
   width: 150px;
   padding: 8px;
   border: 1px solid #2a2a4a;
   border-radius: 8px;
   background: #0a1a33;
   font-size: 0.85rem;
}




body.daytime .prepaidCell { background: #ffffff; border-color: #c8c8e0; }




/* The one this wallet can actually mint. */
.prepaidCell.prepaidCellReady { border-color: #1aa05a; box-shadow: 0 0 0 1px #1aa05a inset; }




.prepaidCellThumb {
   display: block;
   width: 100%;
   height: auto;
   border-radius: 5px;
   background: #caf8ff;
   image-rendering: pixelated;
}




.prepaidCellId {
   display: block;
   margin-top: 6px;
   color: #cdeeff;
   font-weight: 700;
}




body.daytime .prepaidCellId { color: #0c2141; }




/* ⚠️ THE TWO STATES READ DIFFERENTLY ON PURPOSE — one is an instruction, the other is a reassurance. */
.prepaidCellState {
   display: block;
   margin-top: 4px;
   color: #9fc4e8;
   font-size: 0.78rem;
   line-height: 1.35;
}




body.daytime .prepaidCellState { color: #45607f; }




.prepaidCell.prepaidCellReady .prepaidCellState { color: #3ddc8a; font-weight: 600; }




body.daytime .prepaidCell.prepaidCellReady .prepaidCellState { color: #0b7a3f; }




.prepaidCellButton {
   margin-top: 7px;
   padding: 6px 10px;
   width: 100%;
   background-color: #1aa05a;
   border: none;
   border-radius: 6px;
   color: #ffffff;
   font-family: inherit;
   font-size: 0.82rem;
   font-weight: 600;
   cursor: pointer;
}




.prepaidCellButton:hover { background-color: #148048; }




#myPrepaidMore {
   margin-top: 14px;
   font-size: 1.15rem;
}




#myPrepaidMore a {
   color: magenta;
   text-decoration: underline;
   font-weight: 600;
}




#myPrepaidMore a:hover { color: #ffffff; }




body.daytime #myPrepaidMore a { color: magenta; }




body.daytime #myPrepaidMore a:hover { color: #0b7a5a; }




/* ===================== COLLAPSIBLE OPTION CARDS =====================
   ⚠️ COLLAPSED IS THE DEFAULT, AND IT IS SET IN THE MARKUP, NOT BY JS. Each card ships with
   `is-collapsed` on it, so the folded state is what renders on the very first paint — a card that
   starts open and is shut by a script flashes its full height first, and on this page that is three
   cards' worth of text jumping the whole mint area.

   ⚠️ WHAT SURVIVES COLLAPSING IS DELIBERATE: the OPTION label, the button, and — on OPTION 1 only —
   the word RECOMMENDED!. Everything else is in .mintOptionMore. The point is that the three choices
   can be read at a glance instead of scrolled past, which is the opposite problem to the one this card
   was built to fix (it used to open on a bare id field that explained nothing).

   ⚠️ display: none, NOT height: 0. These cards contain a logo image, an <input> and buttons; a
   zero-height overflow-hidden region still lets Tab land on all of them, so a keyboard user would be
   typing into a Punk-ID field they cannot see. Nothing here animates for the same reason — the content
   has no fixed height to transition between. */
.mintOptionButtonDIV.is-collapsed .mintOptionMore {
   display: none;
}




/* The toggle itself: a quiet row at the BOTTOM of the card, under everything it controls. */
.mintOptionToggle {
   display: block;
   margin: 10px auto 0 auto;
   padding: 3px 14px;
   background: transparent;
   border: 1px solid #a9966f;
   border-radius: 999px;
   color: #4a3f2a;
   font-family: inherit;
   font-size: 0.86rem;
   line-height: 1.3;
   cursor: pointer;
   transition: background 0.15s ease, color 0.15s ease;
}




/* ⚠️ NO body.daytime OVERRIDE, ON PURPOSE — .mintOptionButtonDIV is CREAM IN BOTH THEMES, so a light
   override here would be styling against a background that never changes. Same reasoning as
   .mintOptionNote, which carries the identical note a few rules down. */
.mintOptionToggle:hover {
   background: #efe2cd;
   color: #000000;
}




/* The arrow turns to point up once the card is open — the button never changes size. */
.mintOptionArrow {
   display: inline-block;
   transition: transform 0.18s ease;
}




.mintOptionButtonDIV:not(.is-collapsed) .mintOptionArrow {
   transform: rotate(180deg);
}




/* The three route buttons have their OWN class rather than .adminButton — they are the card's primary
   choices, not admin chrome, and they should not inherit that palette or drift with it.
   ⚠️ IT STANDS ALONE: every property .adminButton would have supplied is set here, because the third
   "button" is an <a> and would otherwise arrive with link underline, link colour and inline layout. */
.mintOptionButton {
   display: block;
   margin: 0 auto 8px auto;
   padding: 11px 23px;
   background-color: #2b8aff;
   border: none;
   border-radius: 7px;
   color: #ffffff;
   font-family: inherit;
   font-size: 0.95rem;
   font-weight: 700;
   text-align: center;
   text-decoration: none;
   cursor: pointer;
   transition: background-color 0.2s ease;
}



.mintOptionButton:hover {
   background-color: #4d86ff;
   color: #ffffff;
}



body.daytime .mintOptionButton {
   background-color: #0b59ff;
}



body.daytime .mintOptionButton:hover {
   background-color: #2b6cff;
}



/* The delegate option's RECOMMENDED block + logo: hovering anywhere in here shows the explanation.
   `cursor: help` is the only cue that it is hoverable at all — without it nothing on screen says so. */
.delegateTipTarget {
   cursor: help;
}





/* The bordered FRAME around the delegate.xyz logo lifts and glows on hover, so it reads as the link it is.
   ⚠️ SCOPED BY CLASS, NOT AS `.delegateTipTarget p`. It was the latter until the instruction line above
   became its own <p> and started zooming and ringing along with the logo.
   ⚠️ IT CANNOT RESTYLE THE BORDER ITSELF. That <p> carries an INLINE `border: solid 1px gray`, and inline
   styles beat every stylesheet rule, so a `border-color` hover would silently do nothing — the same trap
   the magenta button hit. The ring is drawn with `box-shadow` instead, which the inline style says nothing
   about, and which sits just outside the existing border rather than replacing it. */
.delegateTipTarget .delegateLogoFrame {
   transition: transform 0.1s ease, box-shadow 0.18s ease, background-color 0.1s ease;
}



.delegateTipTarget .delegateLogoFrame:hover {
   transform: scale(1.04);
   background-color: rgba(43, 108, 255, 0.10);
   box-shadow: 0 0 0 2px rgba(43, 108, 255, 0.55), 0 0 12px rgba(43, 108, 255, 0.30);
}



body.daytime .delegateTipTarget .delegateLogoFrame:hover {
   background-color: rgba(27, 79, 168, 0.07);
   box-shadow: 0 0 0 2px rgba(27, 79, 168, 0.45), 0 0 12px rgba(27, 79, 168, 0.20);
}



/* ⚠️ DARK TEXT, IN BOTH THEMES — because .mintOptionButtonDIV is CREAM in both themes. This was
   #cdeeff, a pale blue chosen when the block sat on the dark panel; once the cards took a light
   background it stayed pale and went nearly invisible in dark mode. A light-mode override cannot fix
   that: the card is light in DARK mode too, so the base colour is the one that has to be readable. */
.mintOptionNote {
   color: #2f4b6b;
   font-size: 0.9rem;
   line-height: 1.4;
   text-align: left;
}



body.daytime #mintOptionsDIV {
   /* background: #eef4ff; */
   border-color: #7da3e8;
}



body.daytime #mintOptionsDIV .mintOptionsHeader {
   color: #1b4fa8;
}



/* No body.daytime override for .mintOptionNote: the card is the same cream in both themes, so one
   colour serves both. Add one here only if the card itself ever becomes theme-dependent. */


#mintCardDIV {
   max-width: 800px;
   margin: 0px auto;
   padding: 30px;
   background-color: #1d1d1d;
   border: 1px solid #a8a8ff;
   border-radius: 9px;
   color: #e3e3e3;
}



#mintCardDIV h3 {
   text-align: center;
   font-size: 2.05rem;
   font-weight: 700;
   color: #0059ff;
   /* color: #00ffcc; */
   margin: 0 0 0px 0;
}

#mintCardDIV h4 {
   text-align: center;
   font-size: 1.75rem;
   font-weight: 700;
   color: #00ffcc;
   margin: 0 0 10px 0;
}



#mintCardDIV p {
   text-align: center;
   color: #cdeeff;
   font-size: 0.95rem;
   margin: 0 0 14px 0;
}



/* ⚠️ THE RULE ABOVE REACHES INSIDE THE OPTION CARDS AND OUTRANKS .mintOptionNote. `#mintCardDIV p` is an
   id plus a type; `.mintOptionNote` is one class, so every <p> in a card — the OPTION labels, the owner
   explanation, the delegate instructions — went back to pale blue on the cream background, no matter what
   .mintOptionNote said. Fixing the note's colour alone was not enough, and the symptom looked identical.
   This is the same specificity trap as `.noPunksButtonsDIV` and the magenta button; the rule of thumb for
   this page: if a colour "will not take", look for an id-scoped element selector above it. */
#mintCardDIV .mintOptionButtonDIV p {
   color: #2f4b6b;
}



#mintPriceLabel {
   color: #00ccff;
   font-weight: 500;
   font-size: 0.95rem;
   text-align: center;
   margin: 10px 0;
}


#totalMintedLabel {
   color: #0059ff;
   font-weight: 600;
   font-size: 1.25rem;
   text-align: center;
   margin-bottom: 12px;
}


#punkIDInputLabel {
   display: block;
   color: white;
   font-size: 1.25rem;
   margin-bottom: 6px;
}




/* Source Punk and owner, shown after a successful lookup. */
#verifiedTag {
   margin-top: 0px;
   color: dodgerblue;
   font-weight: 700;
   font-size: 0.95rem;
}


#verifiedPunkTitle {
   display: block;
   color: #004af6;
}


#verifiedPunkImage {
   display: block;
   margin: 0px auto;
   background-color: #dbfffd;
   width: 200px;
   height: 200px;
   box-sizing: content-box;
   border: 1px solid gray;
   border-radius: 0;
   image-rendering: pixelated;
}


#verifiedTag[hidden] {
   display: none;
}



#eligibilityStatusDIV {
   text-align: center;
   margin: 10px 0;
   margin-top: 15px;
   font-size: 0.95rem;
   min-height: 22px;
}


/* On a successful verify, the status line becomes the STEP 2 prompt — matched to #punkIDInputLabel. */
#eligibilityStatusDIV.step2Prompt {
   color: white;
   font-size: 1.25rem;
}

.eligible    { color: #00ffcc; }
.notEligible { color: #ff6677; }
.checking    { color: #cdeeff; font-style: italic; }

#mintButton {
   background-color: #00b6a4;
   border: none;
   color: #0a0a1a;
   font-family: inherit;
   font-weight: 700;
   font-size: 1.05rem;
   padding: 10px 22px;
   border-radius: 6px;
   letter-spacing: 0.5px;
   transition: all 0.2s;
}

#mintButton:hover:not(:disabled) {
   background-color: #00ffcc;
   box-shadow: 0 0 14px rgba(0, 255, 204, 0.6);
}

#mintButton:disabled {
   background-color: #444;
   color: #888;
   cursor: not-allowed;
   box-shadow: none;
}

.mintCardSubBlock {
   text-align: center;
   margin: 15px 0;
}

.mintCardActions {
   text-align: center;
   margin-top: 10px;
}


/* ============================================================
   PHASE STATUS
   ============================================================ */



/* ============================================================
   COUNTDOWN TIMER
   ============================================================ */
#countdownContainerDIV {
   text-align: center;
   margin: 14px auto 6px auto;
   padding: 14px 16px;
   background-color: #1a1a3a;
   border: 2px solid #00ffcc;
   border-radius: 8px;
   max-width: 360px;
   box-shadow: 0 0 18px rgba(0, 255, 204, 0.3);
}

#countdownLabel {
   color: #cdeeff;
   font-size: 0.9rem;
   font-weight: 600;
   letter-spacing: 0.5px;
   margin-bottom: 4px;
   text-transform: uppercase;
}

#countdownTime {
   color: #00ffcc;
   font-weight: 700;
   font-size: 2rem;
   letter-spacing: 2px;
   text-shadow: 0 0 12px rgba(0, 255, 204, 0.4);
   font-variant-numeric: tabular-nums;
   min-height: 2.4rem;
}

#countdownTime.publicOpenState {
   font-size: 1.4rem;
   letter-spacing: 1px;
}

#countdownDummyControls {
   margin-top: 10px;
   display: flex;
   justify-content: center;
   gap: 8px;
   flex-wrap: wrap;
}

.dummyTimerButton {
   background-color: #2a2a4a;
   border: 1px dashed #777;
   color: #cdeeff;
   font-size: 0.8rem;
   font-weight: 600;
   padding: 4px 12px;
   border-radius: 4px;
   letter-spacing: 0.5px;
   transition: all 0.15s;
}

.dummyTimerButton:hover {
   background-color: #3a3a5a;
   border-color: #aaa;
   color: #fff;
}


#postMintEnterDesignLabButton {
   padding: 12px 22px;
   background-color: magenta;
   color: white;
   font-size: 1rem;
   font-weight: bold;
   white-space: nowrap;   /* keep "ENTER THE DESIGN LAB" on ONE line so the button is always wide enough */
}




 /* ===================== RETURNING-HOLDER "your editions" panel ===================== */
/* NO-BROWSER-WALLET NOTICE. Amber rather than red: nothing is broken — WalletConnect still works —
   so this informs, it does not alarm. Width matches #myEditionsDIV so it shares that column's edge. */
#noWalletNotice {
   max-width: 920px;
   margin: 20px auto 0 auto;
   padding: 14px 18px;
   border: 1px solid #8a6d1f;
   border-radius: 7px;
   background: #221b08;
   color: #f0dfa8;
   font-size: 0.95rem;
   line-height: 1.0;
   text-align: center;
}


#noWalletNotice .noWalletTitle {
   font-size: 1.15rem;
   font-weight: 600;
   line-height: 1.0;
}


/* Its own block, so it always starts on the line below the title rather than wrapping onto it. */
#noWalletNotice .noWalletBody {
   margin-top: 10px;
   color: #bda76a;
   font-size: 1.05rem;
}


#noWalletNotice .adminButton {
   margin-top: 14px;
}


body.daytime #noWalletNotice {
   background: #fff8e6;
   border-color: #e0c877;
   color: #6b5410;
}


body.daytime #noWalletNotice .noWalletBody {
   color: #8a7434;
}




/* ===================== NO-PUNKS NOTICE =====================
   Shown when a wallet IS connected but holds no CryptoPunk — the visitor the mint page otherwise
   dead-ends. Deliberately BLUE, matching the project's own accent (#2b6cff) rather than the AMBER
   #noWalletNotice above: amber is "something is wrong / you are missing a wallet", and this is the
   opposite message — there is a product for you. Two notices in the same colour would read as
   two problems. */
/* ⚠️ SIZED FOR ITS COLUMN, NOT FOR THE PAGE. This lives inside #mintInteractiveCol, where it is the
   swap-in for #mintCardDIV — so it takes the column's width and carries no auto margins of its own.
   It used to be a full-width page banner (max-width 920px, margin auto) and those values would now
   fight the flex column it sits in. */
#noPunksNoticeDIV {
   margin: 0;
   padding: 16px 18px;
   border: 1px solid #2b6cff;
   border-radius: 7px;
   background: #0a0f24;
   color: #cdeeff;
   font-size: 0.9rem;
   line-height: 1.15;
   text-align: center;
}


#noPunksNoticeDIV .noPunksTitle {
   color: #7fb0ff;
   font-family: Arial, Helvetica, sans-serif;
   font-size: 1.02rem;
   font-weight: 600;
   line-height: 1.4;
}


/* The greeting carries the weight; the sentence under it is explanatory and steps back.
   ⚠️ THE COLOUR IS PER THEME, AND PLAIN `blue` IS A LIGHT-MODE COLOUR ONLY. #0000ff on this notice's
   #0a0f24 background is very nearly invisible, which is exactly what an inline style did here. */
#noPunksNoticeDIV .noPunksWelcome {
   display: block;
   margin-bottom: 4px;
   color: #5b9bff;
   font-size: 1.6rem;
   font-weight: 700;
   letter-spacing: 0.4px;
}



/* The sentence under the greeting: normal weight, and readable on whichever background it lands on. */
#noPunksNoticeDIV .noPunksLead {
   color: #cdeeff;
   font-weight: normal;
}


#noPunksNoticeDIV .noPunksBody {
   margin-top: 10px;
   color: #9fc4e8;
   /* text-align: left; */
   font-family: Arial, Helvetica, sans-serif;
   line-height: 1.15rem;
}


#noPunksNoticeDIV .noPunksNote {
   margin-top: 8px;
   color: #7a8ba5;
   font-size: 0.84rem;
}


/* ===================== EDITION PREVIEW STRIP =====================
   Real pieces, scrolling, shown while the drop is closed instead of a button that would lead to a
   page saying "not yet".

   ⚠️ THE AUTO-SCROLL DRIVES scrollLeft, NOT transform, AND THAT IS WHAT MAKES IT DRAGGABLE BY HAND.
   It used to animate `transform: translateX()`, which moves content visually while the element's
   scroll position stays at zero — so turning on scrollbars would have given the user a control
   describing a different coordinate space than the one they could see, and scrolling would appear to
   jump. Moving the same property the mouse moves lets the two compose: the loop runs on its own,
   hovering hands control over, and leaving picks up from wherever they left it.
   The driver is previewAutoScroll() in JS/revolutionsMinter-app.js.

   ⚠️ THERE IS NO HEIGHT HERE ON PURPOSE. The strip is sized by its images (.noPunksTrack img), which
   is why it cannot be found on the container in a style inspector. Change the image height to change
   the strip height. */
#noPunksNoticeDIV .noPunksPreviews {
   margin: 14px -18px 6px -18px;   /* bleed to the notice edges — a strip should run off both sides */
   overflow-x: auto;
   overflow-y: hidden;
   scroll-behavior: auto;          /* NOT smooth: it would fight the per-frame driver */
   -webkit-overflow-scrolling: touch;
   -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
   mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}


/* ⚠️ THE SCROLLBAR'S SPACE IS ALWAYS RESERVED; ONLY THE THUMB APPEARS ON HOVER. Toggling the bar
   itself in and out would resize the strip under the pointer at the exact moment someone reaches for
   it — the content would shift as the control arrived. Hiding just the thumb costs nothing. */
#noPunksNoticeDIV .noPunksPreviews {
   scrollbar-width: thin;
   scrollbar-color: transparent transparent;
}


#noPunksNoticeDIV .noPunksPreviews:hover {
   scrollbar-color: rgba(127, 176, 255, 0.55) transparent;
}


#noPunksNoticeDIV .noPunksPreviews::-webkit-scrollbar {
   height: 8px;
}


#noPunksNoticeDIV .noPunksPreviews::-webkit-scrollbar-track {
   background: transparent;
}


#noPunksNoticeDIV .noPunksPreviews::-webkit-scrollbar-thumb {
   background: transparent;
   border-radius: 4px;
   transition: background 0.18s ease;
}


#noPunksNoticeDIV .noPunksPreviews:hover::-webkit-scrollbar-thumb {
   background: rgba(127, 176, 255, 0.55);
}


body.daytime #noPunksNoticeDIV .noPunksPreviews:hover { scrollbar-color: rgba(27, 79, 168, 0.45) transparent; }


body.daytime #noPunksNoticeDIV .noPunksPreviews:hover::-webkit-scrollbar-thumb { background: rgba(27, 79, 168, 0.45); }


#noPunksNoticeDIV .noPunksTrack {
   display: flex;
   gap: 8px;
   width: max-content;
}


#noPunksNoticeDIV .noPunksTrack img {
   width: 140px;
   height: 140px;
   object-fit: cover;
   border-radius: 6px;
   background: #0a0f24;
   flex: 0 0 auto;
}


body.daytime #noPunksNoticeDIV .noPunksTrack img { background: #dfe8fb; }



/* The two doors, equal weight, one under the other. Stacked rather than shrunk side by side, because a
   squeezed pair of buttons reads as one broken control.
   (This replaced the old `.noPunksVault` text link — its rules went with it, since the class is no
   longer emitted anywhere.)
   ⚠️ STACKED, NOT SIDE BY SIDE (2026-09-27): #revealMintCardLink belongs UNDER #seeWhatsComingButton.
   The two links are already in that order in the markup — `flex-direction: column` is the ONLY thing
   putting one under the other, so do not reorder the JS to "fix" the layout.
   ⚠️⚠️ AND IT IS `#noPunksButtonsDIV`, WITH A HASH. That string is the element's ID; its CLASS is
   `noPunksButtons`. Written as `.noPunksButtonsDIV` this rule matched NOTHING, silently — the container
   lost `display: flex` altogether, the two links fell back to sitting inline, side by side, and the
   layout looked like the CSS had never been written. A dead selector produces no warning anywhere. */
#noPunksNoticeDIV #noPunksButtonsDIV {
   display: flex;
   flex-direction: column;
   align-items: center;   /* each link stays its own width rather than stretching into a full-width bar */
   flex-wrap: wrap;
   gap: 10px;
   justify-content: center;
   margin: 14px 0 6px 0;
}



#noPunksNoticeDIV #noPunksButtonsDIV .adminButton {
   flex: 0 1 auto;
   margin: 0;
   text-decoration: none;
   white-space: nowrap;
}


/* THE SECOND DOOR — "OWN A PUNK? Click here". Magenta at rest, in both themes.
   ⚠️ THE MAGENTA THAT WAS ALREADY IN THIS FILE DOES NOT REACH IT: the only other rule setting it on a
   plain .adminButton is `body.daytime .adminButton:not(.primary):not(.danger):not(.success):hover`, which
   is light mode AND hover — so at rest the link fell back to the shared #444477 and looked unchanged.
   ⚠️ TWO IDs, like the rule below it. The element also carries INLINE styles (size, weight, radius,
   padding) but no background, so a stylesheet rule still owns the colour. */
#noPunksNoticeDIV #revealMintCardLink {
   background-color: magenta;
   color: #ffffff;
}



#noPunksNoticeDIV #revealMintCardLink:hover {
   background-color: #ff5ce6;
}



/* THE PRIMARY DOOR — "MINT AN EDITION". It is the one thing on this notice we want clicked, so it is
   deliberately bigger and louder than the "Own a Punk?" link stacked beneath it, which is a door for the
   few rather than the many.
   ⚠️ SELECTED WITH TWO IDs ON PURPOSE. `#seeWhatsComingButton` alone (1 id) loses to the row's child
   rule above (`#noPunksNoticeDIV #noPunksButtonsDIV .adminButton` = 2 ids + 1 class), so a single-id rule
   here would silently do nothing — the specificity trap this stylesheet has already been bitten by once.
   Keep the ancestor id, and note that the two rules deliberately agree on every property they share
   (margin, text-decoration, white-space) so it does not matter which of them wins those. */
#noPunksNoticeDIV #seeWhatsComingButton {
   display: inline-block;
   background-color: #357aff;
   margin: 0;
   margin-top: 10px;
   padding: 11px 23px;
   /* background-color: #00b6a4; */
   border: none;
   border-radius: 9px;
   box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(0, 255, 204, 0.35);
   color: #04231f;               /* dark ON the teal — far more readable than white at this size */
   font-size: 1.0rem;
   font-weight: 600;
   letter-spacing: 0.125px;
   text-decoration: none;
   white-space: nowrap;
   transition: background-color 0.2s ease, transform 0.12s ease, box-shadow 0.2s ease;
}



#noPunksNoticeDIV #seeWhatsComingButton:hover {
   background-color: #00e6cc;
   box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.35), 0 0 0 3px rgba(0, 255, 204, 0.28);
   transform: translateY(-1px);
}



#noPunksNoticeDIV #seeWhatsComingButton:active {
   box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(0, 255, 204, 0.35);
   transform: translateY(1px);   /* the 2px shadow reads as depth, so the press has to remove it */
}



/* Light mode: the teal survives on white, but the ring and the shadow need toning down or the button
   looks like it is glowing in a room with the lights on. */
body.daytime #noPunksNoticeDIV #seeWhatsComingButton {
   background-color: #357aff;
   box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.18), 0 0 0 1px rgba(0, 120, 110, 0.35);
   color: #ffffff;
}



body.daytime #noPunksNoticeDIV #seeWhatsComingButton:hover {
   background-color: #357aff;
   box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.18), 0 0 0 3px rgba(0, 162, 148, 0.25);
}


#noPunksNoticeDIV .adminButton {
   margin-top: 14px;
   display: inline-block;
   text-decoration: none;
}


body.daytime #noPunksNoticeDIV {
   background: #eef4ff;
   border-color: #7da3e8;
   color: #17283f;
}


body.daytime #noPunksNoticeDIV .noPunksTitle {
   color: #1b4fa8;
}



body.daytime #noPunksNoticeDIV .noPunksWelcome {
   color: blue;
}



body.daytime #noPunksNoticeDIV .noPunksLead {
   color: #040030;
   font-size: 0.95rem;
}


body.daytime #noPunksNoticeDIV .noPunksBody {
   color: #2f4b6b;
}




/* The phrase "composite of generative outputs" is a link to the same page the button below it opens.
   ⚠️ IT HAS TO LOOK LIKE A LINK INSIDE RUNNING TEXT. The body is already a soft blue, so colour alone
   does not read as clickable here — the underline is what distinguishes it from the <strong> around it. */
#noPunksNoticeDIV .noPunksInlineLink {
   color: #7fd0ff;
   text-decoration: underline;
   text-underline-offset: 2px;
   font-weight: 600;
}




#noPunksNoticeDIV .noPunksInlineLink:hover { color: #ffffff; }




body.daytime #noPunksNoticeDIV .noPunksInlineLink { color: #1b4fa8; }




body.daytime #noPunksNoticeDIV .noPunksInlineLink:hover { color: #0b2f6b; }


body.daytime #noPunksNoticeDIV .noPunksNote {
   color: #5d7183;
}




#myEditionsDIV {
   max-width: 920px;
   margin: 20px auto 6px auto;
   padding: 18px;
   border: 1px solid #1f6b45;
   border-radius: 7px;
   background: #0a1f14;
   text-align: center;
}



#myEditionsHeading {
   color: #2b6cff;
   font-size: 1.6rem;
   font-weight: 800;
   letter-spacing: 1px;
   margin: 0 0 6px;
}


#myEditionsSubheading {
   color: #cdeeff;
   font-size: 1.05rem;
   margin: 0 0 16px;
}


#myEditionsList {
   display: flex;
   flex-wrap: wrap;
   gap: 18px;
   justify-content: center;
}


/* Vertical edition card: image on TOP, meta, then the Enter-the-Lab button UNDERNEATH the image. */
.editionCard {
   width: 280px;
   max-width: 300px;
   padding: 14px;
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 7px;
   text-align: center;
   background: #0d0d2b;
   border: 1px solid #2a2a4a;
   border-radius: 10px;
}


.editionThumb {
   width: 100%;
   width: 250px;
   max-width: 260px;
   height: auto;
   border-radius: 0px;
}


/* Thumb SLOT. The server renders a token's pack a few seconds AFTER the mint, so a fresh card's image
   404s at first (see retryEditionThumb). While it is missing the slot shows a spinner, and reserves an
   approximate box so the card doesn't jump when the image pops in. min-height, NOT a hardcoded
   aspect-ratio: the pack poster's proportions change with PACK_ALGOS' length. */
.editionThumbWrap {
   position: relative;
   width: 100%;
   display: flex;
   flex-direction: column;   /* so the "Loading..." label sits UNDER the spinner */
   align-items: center;
   justify-content: center;
   gap: 10px;                /* only ever applies while loading — the other states show a single child */
}


.editionThumbWrap.loading,
.editionThumbWrap.failed {
   min-height: 170px;
   background: #08081c;
   border: 1px dashed #2a2a4a;
   border-radius: 6px;
}


.editionThumbWrap.loading .editionThumb {
   display: none;   /* still fetched + still fires load/error — display:none only hides an <img>, it doesn't cancel it */
}


/* Reuses the `spin` keyframes from the wallet/spinner modal section above. */
.editionThumbSpinner {
   display: none;
   width: 34px;
   height: 34px;
   border: 4px solid rgba(0, 200, 255, 0.2);
   border-top: 4px solid rgb(0, 200, 255);
   border-radius: 50%;
   animation: spin 0.9s linear infinite;
}


.editionThumbWrap.loading .editionThumbSpinner {
   display: block;
}


.editionThumbLoadingLabel {
   display: none;
   color: #8fb3d9;
   font-size: 0.85rem;
   letter-spacing: 0.5px;
}


.editionThumbWrap.loading .editionThumbLoadingLabel {
   display: block;
}


.editionThumbNote {
   display: none;
   padding: 10px 14px;
   color: #8fb3d9;
   font-size: 0.85rem;
   line-height: 1.35;
}


.editionThumbWrap.failed .editionThumbNote {
   display: block;
}


/* Single NFT (one-Punk holder) → show it large. ID-scoped so it beats the base .editionCard/.editionThumb.
   ⚠️ The max-width caps are in % of the viewport, NOT px. As fixed 480/450px these were WIDER THAN A
   PHONE, so the document scrolled horizontally — which made `.navbar { width: 100% }` look broken: the
   bar correctly filled 100% of the viewport while the page scrolled well past its right edge. A fixed
   width anywhere on the page can do this; check here first if that symptom returns. */
#myEditionsList.single .editionCard {
   width: 480px;
   max-width: min(500px, 92vw);
}


#myEditionsList.single .editionThumb {
   width: 450px;
   max-width: min(450px, 86vw);
}


#myEditionsList.single .editionThumbWrap.loading,
#myEditionsList.single .editionThumbWrap.failed {
   min-height: 300px;
}


.editionMeta {
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 3px;
}


.editionTitle {
   color: #cdeeff;
   font-weight: 700;
   font-size: 1.15rem;
}


.editionSub {
   color: #8fb3d9;
   font-size: 0.94rem;
   font-weight: bold;
}


/* The caption above ENTER THE DESIGN LAB. Quieter than .editionSub: it explains the button below it
   rather than describing the NFT. */
.editionLabHint {
   color: #8fb3d9;
   font-size: 0.93rem;
   line-height: 1.35;
   max-width: 330px;
}


.editionEnterButton {
   white-space: nowrap;
   margin-top: 4px;
}


body.daytime #myEditionsDIV {
   background: #eaf7ef;
}


body.daytime #myEditionsHeading {
   color: #1558d6;
}


body.daytime #myEditionsSubheading {
   color: #3a4a6a;
}


body.daytime .editionCard {
   background: #ffffff;
   border-color: #c8c8e0;
}


body.daytime .editionTitle {
   color: #1a1a3a;
}


body.daytime .editionSub {
   color: #3a4a6a;
}


body.daytime .editionLabHint {
   color: #5a6a86;
}


body.daytime .editionThumbWrap.loading,
body.daytime .editionThumbWrap.failed {
   background: #f2f6fb;
   border-color: #c8c8e0;
}


body.daytime .editionThumbNote,
body.daytime .editionThumbLoadingLabel {
   color: #3a4a6a;
}




/* ===================== BATCH-SELECT: "YOUR PUNKS" grid ===================== */
#myPunksDIV {
   width: 100%;
   margin: 0 auto;
   padding: 18px;
   border: 1px solid #737373;
    /* #2b6cff; */
   border-radius: 9px;
   background: #0a0f24;
   text-align: center;
}


/* THE "MINT YOUR REMAINING PUNKS" BLOCK — the same #myPunksDIV, relocated.
   syncMintMorePanel() MOVES the existing element under #myEditionsList when the wallet holds at least
   one NFT and still has un-minted Punks, so the grid meets them where they are already looking. These
   two rules only re-dress it for that position; everything else about the panel is unchanged, because
   it IS the same node with the same listeners. */
   /* ⚠️ `white-space: pre-line` IS WHAT MAKES "\n" IN THE HEADING TEXT ACTUALLY BREAK THE LINE.
      mintMoreText() in JS/revolutionsMinter-app.js returns strings containing "\n", and they are set
      with textContent — so the newline really is in the DOM. HTML then collapses it to a single space
      like any other whitespace, and the text renders on one line with no hint that anything is wrong.
      `pre-line` honours the newlines while still collapsing runs of spaces and still wrapping normally.
      Do NOT "fix" this by switching to innerHTML + <br>: textContent cannot inject markup, and these
      strings are assembled from values read off the chain. */
#mintMoreHeading {
   white-space: pre-line;
   margin: 26px 0 10px;
   padding-top: 18px;
   border-top: 1px solid rgb(156, 230, 255);   /* separates it from the NFT cards above */
   color: #004cff;
   font-size: 1.75rem;
   letter-spacing: 0.5px;
}




#myPunksDIV.inEditions {
   max-width: 620px;
   margin: 0 auto;
   border-color: #1f6b45;   /* adopt the editions panel's green rather than its own blue */
   background: #08170f;
}




/* Persistent two-column mint area: showcase LEFT (ALWAYS shown), interactive RIGHT (batch grid OR mint
   card, JS-swapped). Stacks on narrow screens. */
#mintAreaRow {
   display: flex;
   flex-wrap: wrap;
   gap: 28px;
   justify-content: center;
   align-items: flex-start;
   max-width: 1040px;
   margin: 20px auto;
}
#showcaseCol {
   flex: 0 1 400px;
   min-width: 260px;
   max-width: 440px;
}
#mintInteractiveCol {
   flex: 1 1 380px;
   min-width: 300px;
   max-width: 580px;
}


/* SHOWCASE HIDDEN (a wallet holding an NFT) → the interactive column is the only thing left in the row,
   so it takes the full width and lines up with #myEditionsDIV above it. Both numbers below are that
   panel's 920px: change them together, or the two blocks stop sharing an edge.
   The class is set by showShowcase() in revolutionsMinter-app.js. */
#mintAreaRow.noShowcase {
   max-width: 920px;
}


#mintAreaRow.noShowcase #mintInteractiveCol {
   flex: 1 1 100%;
   max-width: 920px;
}

/* Same reason as #mintMoreHeading above — this heading is fed by the same mintMoreText(). */
#myPunksHeading {
   white-space: pre-line;
   color: #2b6cff;
   font-size: 1.45rem;
   font-weight: 800;
   letter-spacing: 0.1px;
   margin: 0 0 20px;
}




/* TWO VOICES IN ONE HEADING: the greeting loud, the sentence under it quieter.
   ⚠️ IT WORKS AT ALL BECAUSE OF `white-space: pre-line` ABOVE. mintMoreText() returns
   "WELCOME!\n<sentence>", so the greeting really is its own rendered line and `::first-line` lands on
   exactly that word — no span, no innerHTML, and nothing for the JS to keep in sync with the wording.
   🚨 GATED ON `.hasGreeting`, AND THAT GATE IS THE WHOLE TRICK. Two of this heading's four states have
   NO greeting — the post-mint one (`mintMoreCount()` alone) and the all-done one ("You've minted … for
   all of your Punks!") — both single sentences with no newline. Ungated, `::first-line` would simply
   enlarge and recolour the first wrapped line of a plain sentence, which reads as a rendering fault.
   refreshMyPunks() toggles the class with the same condition that decides the wording.
   ⚠️ THE SECOND COLOUR IS NOT A NEW ONE. It is this panel's established secondary pair — the same
   #cdeeff / #3a4a6a that #myPunksSubheading already uses a few rules below — so the heading's quiet half
   matches the instruction line beneath it instead of introducing a third blue.
   ⚠️ `::first-line` ACCEPTS ONLY A SUBSET OF PROPERTIES (font, colour, spacing, decoration). Both of
   these are in it; a margin or a display here would be silently ignored. */
#myPunksHeading.hasGreeting {
   color: #cdeeff;
}




#myPunksHeading.hasGreeting::first-line {
   color: #2b6cff;
   font-size: 2rem;
}


/* Now also hosts the Select-all button, moved in by refreshMyPunks so the instruction and the button
   share one line. inline-flex keeps the text baseline and the button aligned without a wrapper. */
#myPunksSubheading {
   display: inline-flex;
   align-items: center;
   flex-wrap: wrap;
   justify-content: center;
   gap: 8px;
   color: #cdeeff;
   font-size: 1rem;
   margin: 0 0 12px;
}


#myPunksControls {
   display: flex;
   justify-content: center;
   align-items: center;
   gap: 14px;
   flex-wrap: wrap;
   margin-bottom: 14px;
}


#myPunksSummary {
   display: block;   /* own centered line between the grid and the MINT button (margins apply now) */
   color: #8fb3d9;
   font-size: 0.95rem;
   margin: 2px 0 12px;
}


/* Scrollable so a whale's long list doesn't run off the page.
   ⚠️ BOTH GRIDS, ONE RULE. The delegated grid had NO styling of its own, so it fell back to block layout —
   and because .punkCell is itself a column flexbox, every Punk sat on its own line down the page instead
   of filling the row. Sharing the rule rather than copying it means the two grids cannot drift apart, and
   any new grid of .punkCell should be added to this selector rather than given a rule of its own. */
/* The delegate panel is framed like #noPunksNoticeDIV — same border, background, radius and padding.
   ⚠️ DELIBERATELY NOT SHARED WITH THAT RULE. The two say opposite things ("you hold no Punk" vs "you can
   mint these"), and a selector covering both would mean one day's restyling of the editions pitch
   silently changing this panel. Matching values, separate rules. */
#myDelegatedPunksDIV {
   margin: 0 0 18px 0;
   background: #000d43;
   padding: 16px 18px;
   border: 1px solid #2b6cff;
   border-radius: 7px;
   color: #cdeeff;
   text-align: center;
}



body.daytime #myDelegatedPunksDIV {
   background: #eef4ff;
   border-color: #7da3e8;
   color: #17283f;
}



/* MINT SELECTED sits centred under the grid. `.adminButton` is inline-block, so the panel's
   `text-align: center` already places it — this keeps it centred even if that changes. */
#mintSelectedDelegatedButton {
   display: block;
   margin-left: auto;
   margin-right: auto;
}



/* The delegated panel borrows the owned panel's furniture — same controls row, same summary line, same
   MINT SELECTED — because it is the same job with a different destination. */
#myDelegatedPunksControls {
   text-align: center;
   margin-bottom: 8px;
}



#myDelegatedPunksSummary {
   display: block;
   margin: 4px 0 10px 0;
   text-align: center;
   color: #9fc4e8;
   font-size: 0.9rem;
}



/* The one line that says where the NFT lands. Quieter than the heading, never absent. */
/* Sits under MINT SELECTED now, so it is a block with room above it rather than an inline tail on the
   heading. */
.delegatedDestinationNote {
   display: block;
   max-width: 460px;
   margin: 10px auto 0 auto;
   color: #9fb6d4;
   font-size: 0.86rem;
   line-height: 1.4;
}



body.daytime .delegatedDestinationNote,
body.daytime #myDelegatedPunksSummary {
   color: #3a4a6a;
}



#myPunksGrid,
#myDelegatedPunksGrid {
   display: flex;
   flex-wrap: wrap;
   gap: 10px;
   background-color: #002c7d;
   justify-content: center;
   margin-bottom: 16px;
   max-height: 360px;
   overflow-y: auto;
   padding: 14px;
   border: solid 1px gray;
   border-radius: 7px;
}

body.daytime #myPunksGrid,
#myDelegatedPunksGrid {
   display: flex;
   flex-wrap: wrap;
   gap: 10px;
   background-color: #bbd3ff;
   justify-content: center;
   margin-bottom: 16px;
   max-height: 360px;
   overflow-y: auto;
   padding: 14px;
   border: solid 1px gray;
   border-radius: 7px;
}

/* MINT SELECTED: blue when actionable, clearly greyed-out + not-allowed while no Punk is selected. */
#mintSelectedButton,
#mintSelectedDelegatedButton {
   background-color: rgb(0, 85, 255);
   font-size: 1.1rem;
   border-radius: 9px;
   padding: 9px 25px;
}

#mintSelectedButton:disabled,
#mintSelectedDelegatedButton:disabled {
   background-color: #3a3a55;
   color: #9090b0;
   cursor: not-allowed;
   opacity: 0.7;
   box-shadow: none;
}

body.daytime #mintSelectedButton:disabled,
body.daytime #mintSelectedDelegatedButton:disabled {
   background-color: #cfd4e4;
   color: #8890a5;
}

.punkCell {
   position: relative;
   width: 102px;
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 4px;
   padding: 6px;
   border: 1px solid #000000;
   border-radius: 8px;
   background: #0d0d2b;
   cursor: pointer;
   transition: border-color 0.15s, box-shadow 0.15s;
}


.punkCell:hover {
   border-color: #2b6cff;
}

.punkCell.selected {
   border-color: #00ffcc;
   box-shadow: 0 0 8px rgba(0, 255, 204, 0.4);
}

.punkCell.minted {
   opacity: 0.45;
   cursor: default;
}



/* A blue ✓ in the top-right corner of an already-minted Punk — a second, glanceable signal beside the
   dimming and the MINTED badge, so the state reads without looking for words.
   ⚠️ DRAWN WITH ::after, NOT ADDED TO THE MARKUP. Three different functions build these cells
   (refreshMyPunks, refreshDelegatedPunks and the editions grid); a pseudo-element means the tick follows
   the `minted` class wherever it is applied, with no builder left to update.
   ⚠️ The cell's own `opacity: 0.5` fades the tick with everything else — so it is drawn at full strength
   and slightly larger than it would need to be at full opacity. */
.punkCell.minted::after {
   content: "\2713";              /* ✓ */
   position: absolute;
   top: 2px;
   right: 6px;
   color: #2b6cff;
   font-size: 1.15rem;
   font-weight: 700;
   line-height: 1;
   text-shadow: 0 0 3px rgba(0, 0, 0, 0.55);
   pointer-events: none;          /* never intercept a click meant for the cell */
}



body.daytime .punkCell.minted::after {
   color: #1b4fa8;
   text-shadow: 0 0 3px rgba(255, 255, 255, 0.75);
}

/* The delegated grid's box sits in the flow at the BOTTOM of the cell, not pinned to a corner like
   .punkCheckbox below — the cell is a column flexbox, so it simply follows the image and its id. */
.delegatedPunkCheckbox {
   width: 16px;
   height: 16px;
   margin-top: 2px;
   accent-color: #00ffcc;
   cursor: pointer;
}



.punkCheckbox {
   position: absolute; top: 6px; left: 6px; width: 16px; height: 16px; accent-color: #00ffcc; cursor: pointer;
}

.punkCellThumb {
   width: 72px; height: 72px; image-rendering: pixelated; border-radius: 4px; background: transparent;
}

.punkCellId {
   color: #cdeeff; font-size: 0.8rem;
}
.punkCellBadge {
   position: absolute; bottom: 28px; background: rgba(0, 0, 0, 0.72); color: #ff6677; font-size: 0.62rem; font-weight: 700; padding: 1px 5px; border-radius: 3px;
}

.prepaidBadge {
   color: #00ffcc;
}

body.daytime #myPunksDIV {
   background: #e1f5ff;
    /* #eef2fb; */
}

/* Relocated into the editions block — follow that block's light palette, not the blue mint-area one. */
body.daytime #myPunksDIV.inEditions {
   background: #f1fbf5;
   border-color: #b7dcc6;
}

body.daytime #mintMoreHeading {
   border-top-color: rgb(156, 230, 255);
   color: #004cff;
}

body.daytime #myPunksHeading {
   color: #1558d6;
}

/* The light half of the two-voice heading above — again the panel's own secondary (#3a4a6a, as
   #myPunksSubheading uses), with the greeting keeping the light heading blue. */
body.daytime #myPunksHeading.hasGreeting {
   color: #3a4a6a;
}

body.daytime #myPunksHeading.hasGreeting::first-line {
   color: #1558d6;
}

body.daytime #myPunksSubheading {
   color: #3a4a6a;
}

body.daytime #myPunksSummary {
   color: #3a4a6a;
}

body.daytime .punkCell {
   background: #e1feff;
   border-color: #979797;
}

body.daytime .punkCellId {
   color: #1a1a3a;
}






/* ============================================================================
   HOVER TOOLTIPS (ported from the Lab's rectPackedPunks-Styles.css)
   A `.hint-icon` carries a data-tip; initMinterTooltips() drives ONE floating
   #tooltipBubble. This page defines no palette CSS vars, so the colours are
   literal here (with a body.daytime override), unlike the Lab's var-driven copy.
   ============================================================================ */
.hint-icon {
   cursor: help;
   color: #7fa8c9;
   font-size: 0.83em;
   margin-left: 0px;
   vertical-align: top;
   /* vertical-align: middle; */
   user-select: none;
}




.hint-icon:hover {
   color: #00ffcc;
}


body.daytime .hint-icon { color: #4a6b8a; }
body.daytime .hint-icon:hover { color: #0d6efd; }




/* ⚠️ MOVED HERE FROM punkRevolutions-Styles.css (2026-10-05) — that sheet is loaded ONLY by
   revolutionsMinter.html, so the editions pages had the `.hint-icon` above and the comment promising a
   bubble, but no bubble. This sheet is loaded by every page that loads siteChrome.js, which drives them.
   The Lab keeps its own var-driven copy in designLab-Styles.css: it must run offline from file://. */
#tooltipBubble {
   position: fixed;
   top: 0;
   left: 0;
   z-index: 4000;
   max-width: 270px;
   padding: 7px 10px;
   background: #0d0d2b;
   color: #e8f4ff;
   border: 1px solid #00ffcc;
   border-radius: 7px;
   font-family: 'Chakra Petch', sans-serif;
   font-size: 0.85rem;
   line-height: 1.4;
   text-transform: none;
   white-space: normal;
   box-shadow: 0 4px 18px rgba(0, 0, 0, 0.45), 0 0 12px rgba(0, 255, 204, 0.22);
   pointer-events: none;
   opacity: 0;
   transform: translateY(3px);
   transition: opacity 0.09s ease, transform 0.09s ease;
}




/* Opt-in wider bubble: add `data-tip-wide` alongside `data-tip` on the hovered element. Everything else
   keeps the 270px default above. */
#tooltipBubble.tip-wide {
   max-width: 350px;
}




#tooltipBubble.is-visible {
   opacity: 1;
   transform: translateY(0);
}




/* Arrow; --tip-arrow-x is set inline (px from the bubble's left edge). */
#tooltipBubble::after {
   content: "";
   position: absolute;
   left: var(--tip-arrow-x, 50%);
   transform: translateX(-50%);
   border: 6px solid transparent;
}




#tooltipBubble.tip-above::after {
   top: 100%;
   border-top-color: #00ffcc;
}




#tooltipBubble.tip-below::after {
   bottom: 100%;
   border-bottom-color: #00ffcc;
}






#punkIDInput {
   width: 90px;
   max-width: 120px;
   padding: 3px 0px;
   font-family: 'Chakra Petch', sans-serif;
   font-size: 0.95rem;
   background-color: #0d0d2b;
   border: 1px solid #444;
   color: #cdeeff;
   border-radius: 6px;
   text-align: center;
}





/* ============================================================
   ADMIN PANEL
   ============================================================ */
#adminPanelDIV {
   display: none;            /* JS sets to 'block' when the connected wallet is the contract owner */
   max-width: 1000px;
   margin: 30px auto;
   padding: 0 15px;
}


.adminSectionWrapper {
   min-width: 400px;
   max-width: 700px;
   margin: auto;
   margin-bottom: 30px;
   padding: 20px;
   border: solid 1px blue;
   border-radius: 9px;
}


#adminPanelInner {
   background-color: #0d0d2b;
   border: solid 1px rgba(45, 31, 0, 0.6) !important;
   border-radius: 0px !important;
   padding: 20px 24px;
}



#adminPanelTitle {
   color: #ffe096;
   font-weight: 700;
   text-align: center;
   letter-spacing: 1px;
   margin-bottom: 24px;
   text-decoration: underline;
}

.adminSection {
   margin-bottom: 18px;
   padding-bottom: 12px;
   border-bottom: 1px solid white;
}

.adminSection:last-child {
   border-bottom: none;
}

.adminSectionTitle {
   min-width: 500px;
   max-width: 500px;
   margin: auto;
   margin-bottom: 8px;
   text-align: center;
   color: #00ccff;
   font-weight: 700;
   font-size: 1.05rem;
   letter-spacing: 0.5px;
}

.adminRow {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   gap: 10px;
   margin-bottom: 8px;
}

.adminLabel {
   color: #cdeeff;
   font-size: 0.95rem;
   min-width: 130px;
}

.adminInput {
   padding: 6px 10px;
   font-size: 0.95rem;
   font-family: inherit;
   background-color: #050511;
   border: 1px solid #444;
   color: #cdeeff;
   border-radius: 4px;
   flex: 1;
   min-width: 160px;
}

.adminButton {
   background-color: #444477;
   border: none;
   color: white;
   font-family: inherit;
   font-weight: 700;
   font-size: 0.9rem;
   padding: 6px 14px;
   border-radius: 4px;
   transition: background-color 0.2s;
}

.adminButton:hover {
   background-color: #6666aa;
}

/* Variant admin buttons */
.adminButton.primary { background-color: #00b6a4; }
.adminButton.danger  { background-color: #cc3300; }
.adminButton.success { background-color: #00aa44; }

.adminButton.primary:hover { background-color: #00d4be; }
.adminButton.danger:hover  { background-color: #ee5522; }
.adminButton.success:hover { background-color: #22cc66; }

/* Specific admin input widths */
#adminReservationHoursInput { max-width: 100px; }
#adminMintPriceInput        { max-width: 140px; }

/* Inline text inside admin rows (e.g. "hours" after duration input) */
.adminInlineText {
   color: #cdeeff;
}

/* Schedule summary line */
#adminScheduleSummary {
   margin-top: 19px;
   text-align: center;
   color: #cdeeff;
   font-size: 0.9rem;
}

/* Pause status line */
#adminPauseStatus {
   color: #cdeeff;
   margin-bottom: 8px;
   text-align: center;
}

/* Pause-status colour, set by a class from refreshAdminPauseStatus() so it themes for day/night. */
#adminPauseStatus.statusActive { color: #00ffcc; }
#adminPauseStatus.statusPaused { color: #ff6677; }
body.daytime #adminPauseStatus.statusActive { color: #004af6; }
body.daytime #adminPauseStatus.statusPaused { color: #cc0033; }


/* ============================================================
   FOOTER
   ============================================================ */
/* ⚠️ OPT-IN, VIA A CLASS ON <body> — DO NOT MAKE THIS THE DEFAULT. On a page with little content the
   footer otherwise floats up directly under it, leaving a band of empty background beneath, which reads
   as a half-loaded page. This pins it to the bottom of the VIEWPORT when the content is shorter than the
   window, and lets it sit naturally below the content when it is taller — which is why it is
   `margin-top: auto` in a flex column and NOT `position: fixed`. A fixed footer would overlap the
   content on every long page.

   It is opt-in because making <body> a flex column changes the layout of every direct child, and the
   long pages (the mint page, the Lab) have their own arrangements that do not need disturbing. Add
   `class="stickyFooterPage"` to a short page's <body>; add nothing to the others. */
body.stickyFooterPage {
   min-height: 100vh;
   display: flex;
   flex-direction: column;
}

/* Everything above the footer shares the leftover space; the footer takes what it needs at the bottom. */
body.stickyFooterPage > footer { margin-top: auto; }




#FooterDIV {
   background-color: #050511;
   padding: 24px 12px;
   text-align: center;
   color: #8888bb;
   font-size: 1.0rem;
   border-top: 1px solid #222;
   margin-top: 40px;
}

.footerLinkClass {
   color: #cdeeff;
   margin: 0px;
   padding: 0px 20px;
   border-right: solid 1px gray;
   text-align: center;
}

.footerLinkClass:hover {
   color: #00ffcc;
}

.footerLinkClassVisiting {
   color: #ffe096;
   margin: 0 10px;
}

#FooterDIV hr {
   width: 80%;
   height: 1px;
   background-color: rgb(57, 57, 57);
   border: none;
   margin: 14px auto;
}

.footerFinePrint {
   font-size: 0.80em;
}


/* ============================================================
   PUNKAGENT DESIGNER PAGE
   ============================================================ */
#designerCardDIV {
   max-width: 900px;
   margin: 30px auto;
   padding: 30px;
   background-color: #1d1d1d;
   border: 1px solid #a8a8ff;
   border-radius: 9px;
   color: #e3e3e3;
}

#designerCardDIV h2 {
   text-align: center;
   font-weight: 700;
   color: #00ffcc;
   margin: 0 0 6px 0;
   text-shadow: 0 0 10px rgba(0, 255, 204, 0.35);
}

#designerSubHeader {
   text-align: center;
   color: #cdeeff;
   font-style: italic;
   margin-bottom: 24px;
}

#designerPunkRow {
   display: flex;
   flex-wrap: wrap;
   gap: 24px;
   align-items: flex-start;
   margin-bottom: 22px;
}

#designerPunkPanel {
   flex: 0 0 260px;
   text-align: center;
}

/* The frame is on a WRAPPER div, not the image, so the drop-shadow on the
   image can trace just the punk silhouette pixels instead of being trapped
   inside a rectangle. */
.designerPunkFrame {
   display: inline-block;
   padding: 12px;
   background-color: #0d0d2b;
   border: 1px solid #2a2a5a;
   border-radius: 9px;
   line-height: 0;   /* removes the inline-baseline gap under the img */
}

#designerPunkImage {
   width: 240px;
   height: 240px;
   image-rendering: pixelated;
   image-rendering: -moz-crisp-edges;
   image-rendering: crisp-edges;
   /* NO background-color or border on the image itself — see CLAUDE.md
      'PUNK IMAGE FORMAT' section. The drop-shadow traces the visible
      pixels of the transparent PNG. */
   filter: drop-shadow(2px 3px 9px rgba(255, 255, 255, 0.25));
}

#designerPunkTraits {
   margin-top: 12px;
   text-align: left;
   font-size: 0.9rem;
   color: #cdeeff;
   line-height: 1.5;
}

#designerPunkTraits .traitChip {
   display: inline-block;
   background-color: #0d0d2b;
   color: #00ccff;
   border: 1px solid #2a2a5a;
   border-radius: 12px;
   padding: 2px 10px;
   margin: 3px 4px 3px 0;
   font-size: 0.82rem;
}

#designerPunkTypeLabel {
   font-weight: 700;
   color: #ffe096;
   letter-spacing: 0.5px;
}

#designerFormPanel {
   flex: 1 1 360px;
   min-width: 280px;
}

.designerField {
   margin-bottom: 16px;
}

.designerField label {
   display: block;
   color: #00ccff;
   font-weight: 600;
   font-size: 0.95rem;
   margin-bottom: 5px;
   letter-spacing: 0.3px;
}

.designerField input[type="text"],
.designerField textarea,
.designerField select {
   width: 100%;
   padding: 8px 12px;
   background-color: #0d0d2b;
   border: 1px solid #444;
   color: #e3e3e3;
   border-radius: 5px;
   font-family: inherit;
   font-size: 0.95rem;
}

.designerField textarea {
   resize: vertical;
   min-height: 60px;
}

.archetypeGrid {
   display: grid;
   grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
   gap: 8px;
}

.archetypeCard {
   background-color: #0d0d2b;
   border: 1px solid #2a2a5a;
   color: #cdeeff;
   border-radius: 6px;
   padding: 10px 8px;
   text-align: center;
   cursor: pointer;
   transition: all 0.15s;
   font-size: 0.88rem;
}

.archetypeCard:hover {
   border-color: #00ccff;
   background-color: #122047;
}

.archetypeCard.selected {
   border-color: #00ffcc;
   background-color: #1a2a4a;
   color: #00ffcc;
   box-shadow: 0 0 10px rgba(0, 255, 204, 0.3);
}

.speechToggleRow {
   display: flex;
   flex-wrap: wrap;
   gap: 8px;
}

.speechToggle {
   background-color: #0d0d2b;
   border: 1px solid #2a2a5a;
   color: #cdeeff;
   border-radius: 14px;
   padding: 4px 12px;
   cursor: pointer;
   font-size: 0.85rem;
   transition: all 0.15s;
}

.speechToggle.on {
   background-color: #1a2a4a;
   border-color: #00ffcc;
   color: #00ffcc;
}

#designerActions {
   margin-top: 24px;
   display: flex;
   justify-content: center;
   gap: 12px;
   flex-wrap: wrap;
}

#designerBackupActions {
   margin-top: 12px;
   display: flex;
   justify-content: center;
   gap: 10px;
   flex-wrap: wrap;
}

#designerBackupList {
   margin: 14px auto 0 auto;
   max-width: 540px;
   background-color: #050511;
   border: 1px dashed #2a2a5a;
   border-radius: 6px;
   padding: 8px 12px;
   font-family: 'Fira Code', 'Courier New', monospace;
   font-size: 0.8rem;
   color: #8888bb;
   max-height: 180px;
   overflow-y: auto;
   display: none;
}

#designerBackupList.populated {
   display: block;
}

.designerBackupListItem {
   display: flex;
   justify-content: space-between;
   align-items: center;
   padding: 4px 0;
   border-bottom: 1px solid #1a1a3a;
}

.designerBackupListItem:last-child {
   border-bottom: none;
}

.designerBackupListItem .name {
   color: #cdeeff;
   flex: 1 1 auto;
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
   margin-right: 8px;
}

.designerBackupListItem .actions {
   display: flex;
   gap: 6px;
   flex: 0 0 auto;
}

.designerBackupListItem button {
   background-color: #2a2a4a;
   border: 1px solid #444;
   color: #cdeeff;
   font-family: inherit;
   font-size: 0.72rem;
   padding: 2px 8px;
   border-radius: 3px;
   cursor: pointer;
}

.designerBackupListItem button:hover {
   background-color: #3a3a5a;
   border-color: #888;
}

.designerButton {
   background-color: #00b6a4;
   border: none;
   color: #0a0a1a;
   font-family: inherit;
   font-weight: 700;
   font-size: 0.95rem;
   padding: 9px 22px;
   border-radius: 6px;
   letter-spacing: 0.5px;
   transition: all 0.2s;
}

.designerButton:hover {
   background-color: #00ffcc;
   box-shadow: 0 0 14px rgba(0, 255, 204, 0.6);
}

.designerButton.secondary {
   background-color: #2a2a4a;
   color: #cdeeff;
}

.designerButton.secondary:hover {
   background-color: #3a3a5a;
   box-shadow: none;
}

#designerSavedStatus {
   text-align: center;
   margin-top: 14px;
   min-height: 22px;
   color: #00ffcc;
   font-weight: 600;
   font-size: 0.9rem;
}

#designerJsonPreview {
   margin-top: 18px;
   padding: 12px 14px;
   background-color: #050511;
   border: 1px dashed #2a2a5a;
   border-radius: 6px;
   color: #8888bb;
   font-family: 'Fira Code', 'Courier New', monospace;
   font-size: 0.78rem;
   max-height: 220px;
   overflow: auto;
   white-space: pre;
}


/* ============================================================
   CHAT PAGE
   ============================================================ */
#chatCardDIV {
   max-width: 900px;
   margin: 30px auto;
   padding: 24px 28px;
   background-color: #1d1d1d;
   border: 1px solid #a8a8ff;
   border-radius: 9px;
}

#chatCardDIV h2 {
   text-align: center;
   color: #00ffcc;
   font-weight: 700;
   margin: 0 0 4px 0;
   text-shadow: 0 0 10px rgba(0, 255, 204, 0.35);
}

#chatSubHeader {
   text-align: center;
   color: #cdeeff;
   font-style: italic;
   margin-bottom: 18px;
}

#chatHeaderRow {
   margin-bottom: 14px;
   padding-bottom: 14px;
   border-bottom: 1px solid #2a2a5a;
}

#chatIdentity {
   display: flex;
   align-items: center;
   gap: 14px;
   flex-wrap: wrap;
}

#chatPunkImage {
   width: 96px;
   height: auto;
   image-rendering: pixelated;
   image-rendering: -moz-crisp-edges;
   image-rendering: crisp-edges;
   /* Silhouette drop-shadow only — no background/border so it doesn't trace
      a rectangle around the transparent PNG. */
   filter: drop-shadow(2px 3px 7px rgba(255, 255, 255, 0.45));
}

.chatIdentityText {
   flex: 1 1 auto;
   min-width: 0;
}

#chatAgentName {
   font-size: 1.4rem;
   font-weight: 700;
   color: #00ffcc;
   letter-spacing: 0.5px;
}

#chatAgentTagline {
   color: #cdeeff;
   font-size: 0.9rem;
   margin-top: 4px;
   font-style: italic;
}

#chatNoPersonalityWarning {
   color: #ffe096;
   font-size: 0.85rem;
   margin-top: 6px;
}

#chatSettingsRow {
   display: flex;
   flex-wrap: wrap;
   gap: 10px;
   align-items: center;
   margin-bottom: 14px;
   font-size: 0.9rem;
}

#chatSettingsRow label {
   color: #00ccff;
   font-weight: 600;
}

#chatSettingsRow select,
#chatSettingsRow input {
   padding: 6px 10px;
   background-color: #0d0d2b;
   border: 1px solid #444;
   color: #e3e3e3;
   border-radius: 4px;
   font-family: inherit;
   font-size: 0.9rem;
}

#chatApiKeyInput {
   flex: 1 1 220px;
   min-width: 200px;
}

#chatApiKeyToggleButton {
   background-color: #2a2a4a;
   border: 1px dashed #777;
   color: #cdeeff;
   font-family: inherit;
   font-size: 0.78rem;
   padding: 4px 10px;
   border-radius: 4px;
}

#chatMessagesArea {
   background-color: #050511;
   border: 1px solid #2a2a5a;
   border-radius: 6px;
   padding: 16px;
   min-height: 280px;
   max-height: 480px;
   overflow-y: auto;
   margin-bottom: 14px;
}

.chatMsg {
   margin: 0 0 12px 0;
   padding: 10px 14px;
   border-radius: 12px;
   line-height: 1.4;
   white-space: pre-wrap;
   word-wrap: break-word;
   font-size: 0.95rem;
}

.chatMsg.user {
   background-color: #1a2a4a;
   color: #cdeeff;
   margin-left: 40px;
   border: 1px solid #2a3a6a;
}

.chatMsg.agent {
   background-color: #112233;
   color: #00ffcc;
   margin-right: 40px;
   border: 1px solid #1a3a3a;
}

.chatMsg.system {
   background-color: transparent;
   color: #8888bb;
   font-style: italic;
   font-size: 0.85rem;
   text-align: center;
   border: none;
   margin: 6px 0;
}

.chatMsgRole {
   font-size: 0.72rem;
   text-transform: uppercase;
   letter-spacing: 0.6px;
   font-weight: 700;
   opacity: 0.65;
   margin-bottom: 4px;
}

#chatInputRow {
   display: flex;
   gap: 10px;
}

#chatInputBox {
   flex: 1 1 auto;
   min-height: 50px;
   padding: 10px 12px;
   background-color: #0d0d2b;
   border: 1px solid #444;
   color: #e3e3e3;
   border-radius: 6px;
   font-family: inherit;
   font-size: 0.95rem;
   resize: vertical;
}

#chatSendButton {
   background-color: #00b6a4;
   border: none;
   color: #0a0a1a;
   font-family: inherit;
   font-weight: 700;
   font-size: 0.95rem;
   padding: 10px 22px;
   border-radius: 6px;
   letter-spacing: 0.5px;
   transition: all 0.2s;
   align-self: stretch;
}

#chatSendButton:hover:not(:disabled) {
   background-color: #00ffcc;
   box-shadow: 0 0 14px rgba(0, 255, 204, 0.6);
}

#chatSendButton:disabled {
   background-color: #444;
   color: #888;
   cursor: not-allowed;
}

/* Animated dots inside the THINKING… state of the send button. Each dot
   pulses independently with a staggered delay so the trailing "..." reads
   as a left-to-right wave. */
.thinkingDot {
   display: inline-block;
   opacity: 0.25;
   animation: thinkingDotPulse 1.3s ease-in-out infinite;
}

.thinkingDot:nth-child(1) { animation-delay: 0s;    }
.thinkingDot:nth-child(2) { animation-delay: 0.18s; }
.thinkingDot:nth-child(3) { animation-delay: 0.36s; }

@keyframes thinkingDotPulse {
   0%, 60%, 100% { opacity: 0.25; transform: translateY(0); }
   30%           { opacity: 1;    transform: translateY(-1px); }
}

#chatActions {
   margin-top: 12px;
   display: flex;
   gap: 10px;
   flex-wrap: wrap;
   justify-content: flex-end;
}

.chatActionButton {
   background-color: #2a2a4a;
   border: 1px dashed #777;
   color: #cdeeff;
   font-family: inherit;
   font-size: 0.8rem;
   padding: 4px 12px;
   border-radius: 4px;
}

.chatActionButton:hover {
   background-color: #3a3a5a;
   border-color: #aaa;
}

#chatStatus {
   text-align: center;
   color: #ff6677;
   font-size: 0.85rem;
   margin-top: 8px;
   min-height: 20px;
}

#chatTokenInfo {
   text-align: right;
   color: #555577;
   font-size: 0.75rem;
   margin-top: 6px;
   font-family: 'Fira Code', 'Courier New', monospace;
}


/* ============================================================
   COLLECTION PAGE
   ============================================================ */
#collectionCardDIV {
   max-width: 960px;
   margin: 30px auto;
   padding: 24px 28px;
   background-color: #1d1d1d;
   border: 1px solid #a8a8ff;
   border-radius: 9px;
   color: #e3e3e3;
}

#collectionCardDIV h2 {
   text-align: center;
   color: #00ffcc;
   font-weight: 700;
   margin: 0 0 4px 0;
   text-shadow: 0 0 10px rgba(0, 255, 204, 0.35);
}

#collectionSubHeader {
   text-align: center;
   color: #cdeeff;
   font-style: italic;
   margin-bottom: 22px;
}

#collectionControls {
   display: flex;
   flex-wrap: wrap;
   gap: 12px;
   align-items: flex-end;
   margin-bottom: 16px;
   padding: 14px;
   background-color: #0d0d2b;
   border: 1px dashed #2a2a5a;
   border-radius: 8px;
}

#collectionControls .designerField {
   margin-bottom: 0;
   flex: 1 1 200px;
}

#collectionAddressInput {
   width: 100%;
   padding: 8px 12px;
   background-color: #050511;
   border: 1px solid #444;
   color: #cdeeff;
   border-radius: 5px;
   font-family: 'Fira Code', 'Courier New', monospace;
   font-size: 0.85rem;
}

#collectionUseConnectedWalletButton {
   background-color: #2a2a4a;
   border: 1px dashed #777;
   color: #cdeeff;
   font-family: inherit;
   font-size: 0.78rem;
   padding: 6px 12px;
   border-radius: 4px;
   white-space: nowrap;
}

#collectionScanButton {
   background-color: #00b6a4;
   border: none;
   color: #0a0a1a;
   font-family: inherit;
   font-weight: 700;
   font-size: 0.95rem;
   padding: 10px 22px;
   border-radius: 6px;
   letter-spacing: 0.5px;
}

#collectionScanButton:hover:not(:disabled) {
   background-color: #00ffcc;
   box-shadow: 0 0 14px rgba(0, 255, 204, 0.6);
}

#collectionScanButton:disabled {
   background-color: #444;
   color: #888;
   cursor: not-allowed;
}

#collectionStatus {
   text-align: center;
   color: #cdeeff;
   font-size: 0.9rem;
   min-height: 22px;
   margin: 8px 0;
}

#collectionStatus.error {
   color: #ff6677;
}

#collectionSummary {
   text-align: center;
   color: #00ccff;
   font-weight: 700;
   font-size: 1.0rem;
   margin: 12px 0;
}

#collectionGrid {
   display: grid;
   grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
   gap: 14px;
   margin-top: 14px;
}

.collectionCard {
   background-color: #0d0d2b;
   border: 1px solid #2a2a5a;
   border-radius: 6px;
   padding: 8px;
   text-align: center;
   transition: border-color 0.15s, box-shadow 0.15s;
}

.collectionCard:hover {
   border-color: #00ccff;
   box-shadow: 0 0 10px rgba(0, 204, 255, 0.25);
}

.collectionCard .cardImage {
   width: 100%;
   aspect-ratio: 1 / 1;
   background-color: #050511;
   border-radius: 4px;
   margin-bottom: 6px;
   object-fit: contain;
   image-rendering: auto;
}

.collectionCard .cardImage.pixelArt {
   image-rendering: pixelated;
   image-rendering: -moz-crisp-edges;
   image-rendering: crisp-edges;
}

.collectionCard .cardImagePlaceholder {
   width: 100%;
   aspect-ratio: 1 / 1;
   background-color: #1a1a3a;
   border: 1px dashed #2a2a5a;
   color: #555577;
   border-radius: 4px;
   margin-bottom: 6px;
   display: flex;
   align-items: center;
   justify-content: center;
   font-size: 0.75rem;
   text-align: center;
}

.collectionCard .cardCollection {
   color: #00ccff;
   font-size: 0.78rem;
   font-weight: 700;
   letter-spacing: 0.3px;
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
   margin-bottom: 2px;
}

.collectionCard .cardName {
   color: #cdeeff;
   font-size: 0.82rem;
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
}

.collectionCard .cardId {
   color: #555577;
   font-size: 0.7rem;
   margin-top: 4px;
   font-family: 'Fira Code', 'Courier New', monospace;
}

#collectionSaveRow {
   margin-top: 24px;
   text-align: center;
}

#collectionSavedBanner {
   margin: 0 0 14px 0;
   padding: 10px 14px;
   background-color: #122047;
   border-left: 4px solid #00ccff;
   border-radius: 4px;
   color: #cdeeff;
   font-size: 0.9rem;
}


/* ---- Embedded chat panel under the NFT grid ---- */
#collectionChatPanel {
   margin-top: 30px;
   padding: 18px 20px 16px 20px;
   background-color: #0d0d2b;
   border: 1px solid #2a3a6a;
   border-radius: 8px;
   border-top: 3px solid #00ccff;
}

#collectionChatHeader {
   margin: 0 0 4px 0;
   color: #00ffcc;
   font-weight: 700;
   font-size: 1.0rem;
   letter-spacing: 0.5px;
   text-shadow: 0 0 8px rgba(0, 255, 204, 0.25);
}

#collectionChatIdentity {
   color: #cdeeff;
   font-size: 0.85rem;
   font-style: italic;
   margin-bottom: 10px;
}

#collectionChatWarning {
   margin: 8px 0;
   color: #ffe096;
   font-size: 0.85rem;
}

#collectionChatWarning a {
   color: #00ccff;
   text-decoration: underline;
}

#collectionChatMessages {
   background-color: #050511;
   border: 1px solid #2a2a5a;
   border-radius: 6px;
   padding: 14px;
   min-height: 180px;
   max-height: 380px;
   overflow-y: auto;
   margin-bottom: 12px;
}

#collectionChatInputRow {
   display: flex;
   gap: 10px;
}

#collectionChatInput {
   flex: 1 1 auto;
   min-height: 48px;
   padding: 10px 12px;
   background-color: #050511;
   border: 1px solid #444;
   color: #e3e3e3;
   border-radius: 6px;
   font-family: inherit;
   font-size: 0.95rem;
   resize: vertical;
}

#collectionChatSendButton {
   background-color: #00b6a4;
   border: none;
   color: #0a0a1a;
   font-family: inherit;
   font-weight: 700;
   font-size: 0.95rem;
   padding: 10px 22px;
   border-radius: 6px;
   letter-spacing: 0.5px;
   align-self: stretch;
}

#collectionChatSendButton:hover:not(:disabled) {
   background-color: #00ffcc;
   box-shadow: 0 0 14px rgba(0, 255, 204, 0.6);
}

#collectionChatSendButton:disabled {
   background-color: #444;
   color: #888;
   cursor: not-allowed;
}

#collectionChatTokenInfo {
   text-align: right;
   color: #555577;
   font-size: 0.75rem;
   margin-top: 6px;
   font-family: 'Fira Code', 'Courier New', monospace;
}

#collectionChatStatus {
   text-align: center;
   color: #ff6677;
   font-size: 0.85rem;
   margin-top: 8px;
   min-height: 18px;
}

#collectionChatActions {
   margin-top: 10px;
   display: flex;
   gap: 10px;
   flex-wrap: wrap;
   justify-content: flex-end;
   align-items: center;
}

/* Small inline spinner used during scan + save. Reuses the .spinner keyframes
   from the wallet/spinner modal section above. */
.inlineSpinner {
   display: inline-block;
   width: 20px;
   height: 20px;
   border: 3px solid rgba(0, 200, 255, 0.2);
   border-top: 3px solid rgb(0, 200, 255);
   border-radius: 50%;
   animation: spin 0.9s linear infinite;
   vertical-align: middle;
   margin-left: 10px;
}

/* Big, prominent in-card banner that appears while the wallet is being scanned.
   Not a modal — it sits inline at the top of the card content area, takes the
   full width, has a glowing cyan border + pulsing background so the user can't
   miss it. */
#collectionScanProgress {
   display: none;
   align-items: center;
   gap: 18px;
   margin: 14px 0 18px 0;
   padding: 22px 26px;
   background-color: #0d2845;
   border: 2px solid #00ccff;
   border-radius: 10px;
   box-shadow: 0 0 24px rgba(0, 204, 255, 0.45),
               inset 0 0 12px rgba(0, 204, 255, 0.15);
   animation: scanBannerPulse 1.6s ease-in-out infinite;
}

#collectionScanProgress.visible {
   display: flex;
}

#collectionScanProgress .bigSpinner {
   flex: 0 0 auto;
   width: 56px;
   height: 56px;
   border: 5px solid rgba(0, 200, 255, 0.22);
   border-top: 5px solid rgb(0, 230, 255);
   border-radius: 50%;
   animation: spin 0.9s linear infinite;
   box-shadow: 0 0 14px rgba(0, 200, 255, 0.6);
}

#collectionScanProgress .progressText {
   flex: 1 1 auto;
   font-size: 1.15rem;
   font-weight: 700;
   color: #00ffff;
   letter-spacing: 0.5px;
   text-shadow: 0 0 8px rgba(0, 255, 255, 0.5);
}

#collectionScanProgress .progressSubText {
   display: block;
   font-size: 0.85rem;
   font-weight: 400;
   color: #cdeeff;
   font-style: italic;
   margin-top: 4px;
   letter-spacing: 0.3px;
}

@keyframes scanBannerPulse {
   0%, 100% { box-shadow: 0 0 24px rgba(0, 204, 255, 0.45), inset 0 0 12px rgba(0, 204, 255, 0.15); }
   50%      { box-shadow: 0 0 32px rgba(0, 204, 255, 0.75), inset 0 0 18px rgba(0, 204, 255, 0.25); }
}

/* Save button "✓ SAVED" success state */
#collectionSaveButton.saved {
   background-color: #00aa44;
   color: #ffffff;
   box-shadow: 0 0 14px rgba(0, 200, 80, 0.6);
}

#collectionSaveButton:disabled {
   background-color: #444;
   color: #888;
   cursor: not-allowed;
   box-shadow: none;
}

/* Big visible status toast at the top of the card */
#collectionStatus.success {
   color: #00ffcc;
   font-weight: 700;
}


/* ---- Bring-Your-Own-Key row ---- */
#collectionByokRow {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   gap: 10px;
   margin: 0 0 16px 0;
   padding: 12px 14px;
   background-color: #0d0d2b;
   border: 1px dashed #2a2a5a;
   border-radius: 6px;
   font-size: 0.85rem;
}

#collectionByokRow label {
   color: #cdeeff;
   flex: 0 0 auto;
}

#collectionByokInput {
   flex: 1 1 220px;
   min-width: 180px;
   padding: 6px 10px;
   background-color: #050511;
   border: 1px solid #444;
   color: #cdeeff;
   border-radius: 4px;
   font-family: 'Fira Code', 'Courier New', monospace;
   font-size: 0.8rem;
}

#collectionByokRow button {
   background-color: #2a2a4a;
   border: 1px dashed #777;
   color: #cdeeff;
   font-family: inherit;
   font-size: 0.75rem;
   padding: 5px 10px;
   border-radius: 4px;
}

#collectionByokRow button:hover {
   background-color: #3a3a5a;
   border-color: #aaa;
}

#collectionByokHelp {
   width: 100%;
   color: #8888bb;
   font-size: 0.78rem;
   font-style: italic;
   margin-top: 4px;
}


/* ============================================================
   FAQ PAGE
   ============================================================ */
#faqCardDIV {
   max-width: 960px;
   margin: 30px auto;
   padding: 24px 28px;
   background-color: #1d1d1d;
   border: 1px solid #a8a8ff;
   border-radius: 9px;
}

#faqCardDIV h1 {
   text-align: center;
   color: #00ffcc;
   font-weight: 700;
   margin: 0 0 4px 0;
   text-shadow: 0 0 10px rgba(0, 255, 204, 0.35);
}

#faqSubHeader {
   text-align: center;
   color: #cdeeff;
   font-style: italic;
   margin-bottom: 22px;
}

#faqTOC {
   display: flex;
   flex-wrap: wrap;
   justify-content: center;
   gap: 8px;
   padding: 14px;
   margin-bottom: 24px;
   background-color: #0d0d2b;
   border: 1px dashed #2a2a5a;
   border-radius: 8px;
}

.faqTocLink {
   background-color: #1a2a4a;
   border: 1px solid #2a3a6a;
   color: #cdeeff;
   font-family: inherit;
   font-weight: 600;
   font-size: 0.82rem;
   padding: 4px 12px;
   border-radius: 14px;
   letter-spacing: 0.5px;
   text-transform: uppercase;
   transition: all 0.15s;
}

.faqTocLink:hover {
   border-color: #00ffcc;
   color: #00ffcc;
   background-color: #122047;
}

.faqSection {
   margin-bottom: 28px;
   scroll-margin-top: 20px;
}

.faqSectionHeader {
   color: #00ccff;
   font-weight: 700;
   font-size: 1.15rem;
   letter-spacing: 0.5px;
   text-transform: uppercase;
   margin: 0 0 12px 0;
   padding-bottom: 6px;
   border-bottom: 1px solid #2a2a5a;
}

.faqItem {
   margin-bottom: 6px;
   border: 1px solid #2a2a5a;
   border-radius: 6px;
   overflow: hidden;
   background-color: #050511;
}

.faqQuestion {
   width: 100%;
   text-align: left;
   background-color: transparent;
   border: none;
   color: #cdeeff;
   font-family: inherit;
   font-weight: 600;
   font-size: 1.0rem;
   padding: 12px 14px;
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 12px;
   transition: background-color 0.15s, color 0.15s;
}

.faqQuestion:hover {
   background-color: #0d0d2b;
   color: #00ffcc;
}

.faqQuestion::after {
   content: '+';
   color: #00ffcc;
   font-weight: 700;
   font-size: 1.2rem;
   transition: transform 0.2s;
   flex: 0 0 auto;
}

.faqQuestion.open {
   color: #00ffcc;
   background-color: #0d0d2b;
}

.faqQuestion.open::after {
   content: '\2212';   /* minus sign */
   transform: rotate(0);
}

.faqAnswer {
   max-height: 0;
   overflow: hidden;
   transition: max-height 0.3s ease;
   padding: 0 14px;
   color: #cdeeff;
   font-size: 1.0rem;
   line-height: 1.55;
}

.faqAnswer.open {
   max-height: 1400px;
   padding: 4px 14px 14px 14px;
}

.faqAnswer p {
   margin: 8px 0;
}

.faqAnswer code {
   background-color: #1a1a3a;
   color: #00ffcc;
   padding: 1px 6px;
   border-radius: 3px;
   font-size: 0.85rem;
   font-family: 'Fira Code', 'Courier New', monospace;
}

.faqAnswer ul {
   margin: 8px 0;
   padding-left: 22px;
}

.faqAnswer li {
   margin: 4px 0;
}

/* Persona tags used on USAGE EXAMPLES section */
.useCaseTag {
   display: inline-block;
   padding: 2px 8px;
   border-radius: 10px;
   font-size: 0.7rem;
   font-weight: 700;
   letter-spacing: 0.5px;
   margin-right: 8px;
   vertical-align: middle;
   line-height: 1.3;
}

.tag-general   { background-color: #1a3a4a; color: #00ccff; border: 1px solid #00ccff; }
.tag-artist    { background-color: #3a1a3a; color: #ff66cc; border: 1px solid #ff66cc; }
.tag-founder   { background-color: #3a3a1a; color: #ffe096; border: 1px solid #ffe096; }
.tag-collector { background-color: #2a1a3a; color: #c08cff; border: 1px solid #c08cff; }


/* ============================================================
   FAQ THEME TOGGLE (Day / Night)
   ============================================================ */
#faqThemeToggleRow {
   display: flex;
   justify-content: center;
   margin: 6px 0 18px 0;
}

.themeToggle {
   display: inline-flex;
   align-items: center;
   gap: 10px;
   cursor: pointer;
   user-select: none;
}

.themeToggle input {
   /* Hide the actual checkbox; we render our own track/thumb. */
   position: absolute;
   opacity: 0;
   pointer-events: none;
}

.themeToggleTrack {
   width: 54px;
   height: 28px;
   background-color: #1a1a3a;
   border: 1px solid #2a2a5a;
   border-radius: 14px;
   position: relative;
   transition: background-color 0.2s, border-color 0.2s;
}

.themeToggleThumb {
   position: absolute;
   top: 2px;
   left: 2px;
   width: 22px;
   height: 22px;
   border-radius: 50%;
   background-color: #00ffcc;
   box-shadow: 0 0 6px rgba(0, 255, 204, 0.6);
   transition: left 0.2s, background-color 0.2s, box-shadow 0.2s;
}

.themeToggle input:checked + .themeToggleTrack {
   background-color: #ffe096;
   border-color: #d8a838;
}

.themeToggle input:checked + .themeToggleTrack .themeToggleThumb {
   left: 28px;
   background-color: #fff7d8;
   box-shadow: 0 0 10px rgba(255, 240, 150, 0.95);
}

.themeToggleLabel {
   color: #cdeeff;
   font-weight: 600;
   font-size: 0.9rem;
   letter-spacing: 0.5px;
}


/* ============================================================
   DAYTIME THEME (applied as body.daytime)
   Only the FAQ page wires up the toggle. Other pages never set
   the .daytime class, so they stay dark.
   ============================================================ */
body.daytime {
   background-color: #f4f4f8;
   color: #1a1a3a;
}

/* Nav */
body.daytime .bg-dark {
   background-color: #e8e8f4 !important;
   box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.08) !important;
}

body.daytime .navbar-dark .navbar-nav .nav-link,
body.daytime .navbar-toggler {
   color: #1a1a3a;
}

body.daytime .navbar-dark .navbar-nav .nav-link:hover {
   color: #0088aa;
}

body.daytime .navbar-toggler {
   border-color: rgba(0, 0, 0, 0.15);
}

body.daytime .navbar-toggler-icon {
   background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba%2826, 26, 58, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");
}

body.daytime #PunkRevolutionsLogoDIV {
   color: #0088aa;
   text-shadow: 0 0 6px rgba(0, 136, 170, 0.25);
}

/* Wallet bar */
body.daytime #walletInfoWrapperDIV {
   background-color: #d8e4f4;
   border-top-color: #b8c4d4;
   color: #1a1a3a;
}

/* The light half of the warning: #ff4d5e is tuned for the dark navy bar and goes washed-out on the pale
   one, so the day theme takes a deeper red. Same rule as every other hardcoded dark colour here. */
body.daytime #connectedWalletLabel.notConnected {
   color: #c3001b;
}

body.daytime #connectedWalletLabel,
body.daytime #connectedBlockchainNetworkLabel {
   color: #0010ff;
    /* #005588; */
}

/* FAQ card */
body.daytime #faqCardDIV {
   background-color: #ffffff;
   border-color: #c8c8e0;
   color: #1a1a3a;
}

body.daytime #faqCardDIV h1 {
   color: #0088aa;
   text-shadow: 0 0 6px rgba(0, 136, 170, 0.2);
}

body.daytime #faqSubHeader {
   color: #555577;
}

/* TOC */
body.daytime #faqTOC {
   background-color: #f0f0fa;
   border-color: #c8c8e0;
}

body.daytime .faqTocLink {
   background-color: #ffffff;
   border-color: #b8b8d0;
   color: #1a1a3a;
}

body.daytime .faqTocLink:hover {
   background-color: #e8f4f8;
   border-color: #0088aa;
   color: #0088aa;
}

/* Section headers */
body.daytime .faqSectionHeader {
   color: #0066aa;
   border-bottom-color: #c8c8e0;
}

/* Accordion */
body.daytime .faqItem {
   background-color: #fafafd;
   border-color: #c8c8e0;
}

body.daytime .faqQuestion {
   color: #1a1a3a;
}

body.daytime .faqQuestion:hover {
   background-color: #e8f4f8;
   color: #006688;
}

body.daytime .faqQuestion::after {
   color: #0088aa;
}

body.daytime .faqQuestion.open {
   color: #006688;
   background-color: #e8f4f8;
}

body.daytime .faqAnswer {
   color: #1a1a3a;
}

body.daytime .faqAnswer code {
   background-color: #f0f0fa;
   color: #aa0088;
   border: 1px solid #d8d8e8;
}

/* Theme toggle label color in day mode */
body.daytime .themeToggleLabel {
   color: #1a1a3a;
}

/* Footer */
body.daytime #FooterDIV {
   background-color: #e8e8f4;
   color: #555577;
   border-top-color: #c8c8e0;
}

body.daytime .footerLinkClass {
   color: #1a1a3a;
}

body.daytime .footerLinkClass:hover {
   color: #0088aa;
}

body.daytime .footerLinkClassVisiting {
   color: #aa6600;
}

body.daytime #FooterDIV hr {
   background-color: #c8c8e0;
}

/* Use-case tag daytime overrides */
body.daytime .tag-general   { background-color: #e0f4fa; color: #006688; border-color: #0088aa; }
body.daytime .tag-artist    { background-color: #fae0f4; color: #aa0066; border-color: #aa0088; }
body.daytime .tag-founder   { background-color: #faf4e0; color: #aa6600; border-color: #aa8800; }
body.daytime .tag-collector { background-color: #efe4fa; color: #6633aa; border-color: #8855cc; }

/* Mint card (the mint page's main panel + children) — was dark-only; give it a light scheme in day mode. */
body.daytime #mintCardDIV {
   background-color: #ffffff;
   border-color: #8f8fe0;
   color: #1a1a3a;
}

body.daytime #mintCardDIV h3,
body.daytime #mintCardDIV h4 {
   color: #0059ff;
}

body.daytime #mintCardDIV p {
   color: #3a4a6a;
}

body.daytime #mintPriceLabel,
body.daytime #totalMintedLabel {
   color: #0077aa;
}

body.daytime #punkIDInputLabel {
   color: #1a1a3a;
}

body.daytime #punkIDInput {
   background-color: #ffffff;
   border-color: #b8c4d4;
   color: #1a1a3a;
}

/* #mintConnectPrompt sets color inline → needs !important to flip in day mode. */
body.daytime #mintConnectPrompt {
   color: #1a1a3a !important;
}

body.daytime #eligibilityStatusDIV.step2Prompt {
   color: #1a1a3a;
}

body.daytime .checking { color: #3a4a6a; }
body.daytime .eligible { color: #008877; }

/* #mintRevealDIV sets its dark card colors inline → override with !important. */
body.daytime #mintRevealDIV {
   background: #eaf7ef !important;
   border-color: #1f6b45 !important;
   color: #1a1a3a;
}

/* Countdown timer (mint page) — dark-only base; light it up in day mode too. */
body.daytime #countdownContainerDIV {
   background-color: #ffffff;
   border-color: #008877;
   box-shadow: 0 0 12px rgba(0, 136, 119, 0.2);
}

body.daytime #countdownLabel {
   color: #0077aa;
}

body.daytime #countdownTime {
   color: #008877;
   text-shadow: none;
}

body.daytime .dummyTimerButton {
   background-color: #eef1f8;
   border-color: #b8c4d4;
   color: #3a4a6a;
}

/* Phase status colours (mint page) — bright-on-dark → readable-on-light. */

/* Mint button: WHITE label in day mode (the dark label was tuned for the neon-dark theme), and a
   darker hover so the white text keeps contrast (the base hover goes near-white). */
body.daytime #mintButton {
   color: #ffffff;
}

body.daytime #mintButton:hover:not(:disabled) {
   background-color: #008877;
   color: #ffffff;
}

/* Plain connect/verify buttons (.adminButton with NO colour variant) → day accent. The :not() guards
   keep the .primary/.danger/.success admin-panel variants on their own colours. */
body.daytime .adminButton:not(.primary):not(.danger):not(.success) {
   background-color: #0088aa;
   color: #ffffff;
}

body.daytime .adminButton:not(.primary):not(.danger):not(.success):hover {
   background-color: magenta;
   /* background-color: #00a0c8; */
}

/* Admin panel (owner-only) */
body.daytime #adminPanelInner {
   background-color: #ffffff;
   border-color: rgba(170, 120, 0, 0.5);
}

body.daytime #adminPanelTitle {
   color: #aa7700;
}

body.daytime .adminSection {
   border-bottom-color: transparent;
   /* border-bottom-color: #d8d8e8; */
}

body.daytime .adminSectionTitle {
   color: #0059ff;
}

body.daytime .adminLabel,
body.daytime .adminInlineText,
body.daytime #adminScheduleSummary,
body.daytime #adminPauseStatus {
   color: #3a4a6a;
}

body.daytime .adminInput {
   background-color: #ffffff;
   border-color: #b8c4d4;
   color: #1a1a3a;
}

/* Wallet icon: the night filter colourises the icon for the DARK navbar. On the LIGHT navbar just show
   the image's natural appearance (a dark wallet — the same look you get on hover), which reads fine on
   light. (brightness(0) was wrong: the PNG isn't transparent line-art, so it masked to a black blob.) */
body.daytime #walletIconLink img {
   filter: none;
}




/* ===================== SITE CHROME — navbar, beanie, logo word, theme toggle =====================
   ⚠️ THESE RULES USED TO LIVE INSIDE revolutionsMinter.html. The markup moved to JS/siteChrome.js so
   every page shares one navbar — but the STYLING stayed behind, so editionsMinter.html and
   editionsAdmin.html rendered the same markup unstyled: a tiny beanie, a tiny theme toggle, a logo
   that did not animate. Shared markup needs shared styling or it is not shared at all.
   The responsive half sits at the very end of this file, with the rest of the responsive rules. */

nav.navbar .container { position: relative; }
nav.navbar .container > a:first-of-type {
   position: absolute;
   left: 50%;
   top: 50%;
   transform: translate(-50%, -50%);
   margin: 0;
}

/* Sherone beanie badge (top-left, links to @Sherone33). */
#sheroneBeanieDIV { position: absolute; top: 6px; left: 8px; z-index: 3000; text-align: center; }
#BeanieImage { width: 72px; height: auto; image-rendering: pixelated; transition: transform 0.15s ease, filter 0.15s ease; }
#BeanieImage:hover { transform: scale(1.08); filter: drop-shadow(0 0 8px rgba(0, 0, 0, 0.45)); }

/* Cycling logo word (IMPRESSIONS → IMPROVISATIONS → REVOLUTIONS). JS swaps the text on the fade;
   this transition drives the cross-fade. Duration must match FADE in startMinterTitleWordCycle. */
#wordToAnimate { display: inline-block; text-align: left; font-style: normal; text-transform: none; transition: opacity 0.45s ease; }

/* Day/night toggle switch — same component as designLab.html, but SMALLER + SQUARE, in its OWN corner
   div (top-right, mirroring #sheroneBeanieDIV). The checkbox toggles `body.daytime` (light theme). */
/* ⚠️ THE VISIBLE BUTTON IS `.theme-track`, NOT #themeToggleDIV, .switch, or the checkbox.
   Those three are invisible scaffolding: the div positions, the label sizes, the input carries
   state at opacity 0. `.theme-track` is the span layered over all of it (`inset: 0`) that paints
   the background, border and radius — so that is where to look for anything you can SEE.
   These were one-liners until 2026-09-17 and the border-radius was genuinely hard to find. */
/* ⚠️ IN THE FLOW AT EVERY WIDTH — never absolutely positioned. It used to be
   `position: absolute; top: 14px; right: 12px`, which caused all three of its bugs at once:
     • it OVERLAPPED the animated header word (REVOLUTIONS / Impressions / Improvisations),
       because an out-of-flow box has no idea the text is there;
     • it overlapped the FAQ links on desktop, for the same reason;
     • it never lined up with the hamburger, because its vertical centring and the hamburger's
       were two independent calculations that only agreed by accident.
   As a flex item of .container it cannot overlap anything, and `.container`'s
   `align-items: center` aligns it with the hamburger BY CONSTRUCTION.
   `margin-left: auto` pushes it right; `margin-right` is the gap to the hamburger. */
.theme-toggle {
   display: flex;
   align-items: center;
}

.switch {
   position: relative;
   display: inline-block;
   width: 52px;
   height: 26px;
   /* Bootstrap Reboot gives EVERY <label> `margin-bottom: 0.5rem` (Bootstrap css ~line 242), and
      this control is a <label>. Clear it so flex centering aligns the visible switch with the
      hamburger, rather than its margin box.
      ⚠️ The trap, because it cost hours: FLEX ALIGNS MARGIN BOXES, but getBoundingClientRect()
      reports the BORDER box — so the 8px is invisible to measurement. Both elements measured
      30px tall and still sat 4px apart. If flex siblings look misaligned while every number says
      they match, read their computed MARGIN first, and check the reset stylesheet for bare-element
      rules before assuming the bug is in your own CSS. */
   margin-top: 0;
   margin-bottom: 0;
   align-self: center;
   margin-left: auto;
   margin-right: 10px;
}

.switch input {
   position: absolute;
   inset: 0;
   width: 100%;
   height: 100%;
   margin: 0;
   opacity: 0;     /* invisible but still the thing that gets clicked + holds the checked state */
   cursor: pointer;
   z-index: 2;
}

.theme-track {
   position: absolute;
   inset: 0;
   border-radius: 4px;
   background: #23233a;
   border: 1px solid #3a3a55;
   display: flex;
   align-items: center;
   justify-content: space-between;
   padding: 0 5px;
   font-size: 11px;
   transition: background 0.25s, border-color 0.25s;
}

.theme-track .moon {
   color: #cfe6ff;
   font-size: 23px;
}

.theme-track .sun {
   color: #fff701;
   font-size: 23px;
}

.theme-knob {
   position: absolute;
   top: 3px;
   left: 3px;
   width: 20px;
   height: 20px;
   border-radius: 4px;
   background: #23e0e0;
   box-shadow: 0 0 8px rgba(35, 224, 224, 0.55);   /* a GLOW, not a drop-shadow — deliberate */
   transition: transform 0.25s, background 0.25s, box-shadow 0.25s;
   pointer-events: none;
}

#darkAndLightModeToggleSwitch:checked ~ .theme-track {
   background: #d6ddee;
   border-color: #b9c3da;
}

#darkAndLightModeToggleSwitch:checked ~ .theme-track .moon {
   color: #9aa0b8;
}

#darkAndLightModeToggleSwitch:checked ~ .theme-track .sun {
   color: #ff9d0a;
}

#darkAndLightModeToggleSwitch:checked ~ .theme-knob {
   transform: translateX(26px);
   background: #ffb020;
   box-shadow: 0 0 10px rgba(255, 176, 32, 0.6);
}


/* ===================== RESPONSIVE / MOBILE — KEEP THIS SECTION LAST IN THE FILE =====================
   Position is doing real work here. These overrides use the same specificity as the base rules they
   override (one id, or one class), so the ONLY reason they win is that they come later. Add a new base
   rule below this block and its mobile override will stop applying, with no error and no warning —
   just a greyed-out rule in the inspector. Page-inline elements (beanie, day/night toggle, mint split
   columns) are handled in the page's own <style>, because their base rules are inline and would
   otherwise win the cascade. ===================== */
/* ===================== RESPONSIVE / MOBILE (elements whose base rules live in THIS file) =====================
   Page-inline elements (beanie, day/night toggle, mint split columns) are handled in the page's own <style>,
   because their base rules are inline and would otherwise win the cascade. */
/* ⚠️ THE NAVBAR'S CONTAINER IS NOT MAX-WIDTH-CAPPED WHILE THE HAMBURGER IS VISIBLE (below 992px).
   `.container` normally caps at 540/766px and CENTRES, which means the hamburger's distance from the
   right edge changes continuously with viewport width — and the day/night toggle is positioned from
   that edge. Uncapping it inside the navbar makes the geometry constant (navbar 16px + container 15px
   = 31px to the button's right edge) so one offset works across the whole band. The cap still applies
   to every other .container on the page. */
@media (max-width: 991.98px) {
   .navbar > .container { max-width: none; }

   /* ⚠️ THE HAMBURGER'S SIZE IS MIRRORED BY THE DAY/NIGHT SWITCH so the two read as a matched pair.
      `.switch` in revolutionsMinter.html's own <style> carries THE SAME numbers at each of the three
      bands — 40x40 here, 40x32 at ≤640, 36x30 at ≤460. Change one, change the other, or they stop
      lining up. Sized explicitly rather than left to emerge from padding + em maths, which is also
      what makes the toggle's `right` offset computable.
      Everything is border-box (see the reset at the top of this file), so these numbers are the
      RENDERED size, borders included — which is why both elements measure the same. */
   .navbar-toggler {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 40px;
      height: 40px;
      padding: 0;
      font-size: 1rem;
   }
   .navbar-toggler-icon { width: 24px; height: 24px; }
}




@media (max-width: 640px) {
   /* ---- NAVBAR VERTICAL KNOBS (≤ 640px) — tune these three; they are independent ----
      1. margin-top   → pushes the WHOLE BAR down from the top of the screen. 0 = flush.
      2. padding      → space INSIDE the bar, above and below its contents. This is what was
                        pushing .container down: the <nav> carries `py-3`, and `.navbar.py-3`
                        (two classes) beats plain `.navbar`, so the selector below needs `.py-3`
                        or it will not win.
      3. min-height   → the bar's floor height. Contents are vertically CENTRED in it, so lowering
                        the padding alone will not shrink the bar below this number.
      Values below match what was in force before these knobs existed — change freely. */
   .navbar { margin-top: 0; min-height: 70px; }
   .navbar.py-3 { padding-top: 1rem; padding-bottom: 1rem; }


   /* Full-bleed on phones: the rounded corners read as a floating card at desktop width, but at
      920px-capped-to-the-viewport the panel already spans the screen, so the radius just clips the
      edges oddly. Kept at 0 rather than removed so the desktop value above stays visible and the
      override is obviously deliberate. The `auto` sides preserve the centring from the base rule. */
   #myEditionsDIV { border-radius: 0; margin: 7px auto 6px auto; }

   /* ⚠️ TWO LAYERS OF PADDING inset the bar's contents, and on a phone they cost 15% of the screen:
      .navbar's own 1rem PLUS .container's 15px = 31px a side. The element is full-width either way
      (the inspector reads 402 x 70 on a 402px viewport) — it is the CONTENTS that looked inset.
      Cut both for mobile. THIS CHANGES THE THEME-TOGGLE OFFSET: it is measured from the right edge
      inward, so 8 + 6 = 14px to the hamburger's right edge, + its 40px width + a 10px gap = 64px. */
   .navbar { padding-left: 8px; padding-right: 8px; }
   .navbar > .container { padding-left: 6px; padding-right: 6px; }

   /* HAMBURGER — explicitly sized on mobile, and the size is LOAD-BEARING. The day/night toggle is
      absolutely positioned to sit just left of this button, and its `right` offset is computed from
      this width (see `.switch` in revolutionsMinter.html's own <style>). Width here is set
      directly rather than left to emerge from padding + em maths, so that offset stays predictable.
      CHANGE ONE, CHANGE THE OTHER. */
   .navbar-toggler {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 40px;
      height: 32px;
      padding: 0;
      font-size: 1rem;
   }
   .navbar-toggler-icon { width: 22px; height: 22px; }

   #PunkRevolutionsLogoDIV { font-size: 1.93rem; letter-spacing: 0; }   /* was 2.75rem — far too big on phones */
   #mintCardDIV { padding: 16px 14px; margin: 16px auto; }
   #mintCardDIV h3 { font-size: 1.5rem; }
}




@media (max-width: 460px) {
   /* ---- NAVBAR VERTICAL KNOBS (≤ 460px) — tune these three; they are independent ----
      1. margin-top   → pushes the WHOLE BAR down from the top of the screen. 0 = flush.
      2. padding      → space INSIDE the bar, above and below its contents. This is what was
                        pushing .container down: the <nav> carries `py-3`, and `.navbar.py-3`
                        (two classes) beats plain `.navbar`, so the selector below needs `.py-3`
                        or it will not win.
      3. min-height   → the bar's floor height. Contents are vertically CENTRED in it, so lowering
                        the padding alone will not shrink the bar below this number.
      Values below match what was in force before these knobs existed — change freely. */
   .navbar { margin-top: 0; min-height: 70px; }
   .navbar.py-3 { padding-top: 1rem; padding-bottom: 1rem; }

   /* Full-bleed on phones: the rounded corners read as a floating card at desktop width, but at
      920px-capped-to-the-viewport the panel already spans the screen, so the radius just clips the
      edges oddly. Kept at 0 rather than removed so the desktop value above stays visible and the
      override is obviously deliberate. The `auto` sides preserve the centring from the base rule. */
   #myEditionsDIV { border-radius: 0; margin: 7px auto 6px auto; }

   /* Edge to edge on the smallest screens — every pixel of a 390px viewport counts.
      The hamburger gets its breathing room from its OWN margin rather than from padding on the bar:
      padding here would re-inset the logo and the beanie too, which is the space we just reclaimed.
      ⚠️ That margin is part of the toggle offset: 10px margin + the 36px button + a 10px gap = 56px. */
   .navbar { padding-left: 0; padding-right: 0; }
   .navbar > .container { padding-left: 0; padding-right: 0; }

   .navbar-toggler { width: 36px; height: 30px; margin-right: 10px; }
   .navbar-toggler-icon { width: 20px; height: 20px; }

   #PunkRevolutionsLogoDIV { font-size: 1.65rem; }
   #mintCardDIV h3 { font-size: 1.3rem; }


   #connectedWalletLabel {
      margin-right: 7px;
   }

   #myPunksDIV {
      padding: 7px;
      border: 1px solid #2b6cff;
      border-radius: 9px;
      background: #0a0f24;
      text-align: center;
   }


   #myPunksHeading {
      font-size: 1.15rem;
      font-weight: 800;
      letter-spacing: 0.1px;
      margin: 0 0 20px;
   }


   #myPunksHeading.hasGreeting::first-line {
      font-size: 1.55rem;
   }

}




/* Phones and tablets, including wide tablet viewports with touch input. */
@media (max-width: 991.98px), (any-pointer: coarse) {
   /* Override the wallet margin resets in the later stylesheet and page styles. */
   #walletInfoWrapperDIV #walletInfoDIV {
      margin-left: 5px;
   }
}





/* Keep wallet details on one line on the narrowest phones, including iPhone SE. */
@media (max-width: 375px) {
   #walletInfoWrapperDIV .walletConnectedPrefix { display: none; }




   #walletInfoWrapperDIV #walletInfoDIV { font-size: 0.85rem; }




   #walletInfoWrapperDIV #connectedWalletLabel { margin-right: 4px; }
}




/* ===================== SITE CHROME — RESPONSIVE =====================
   Kept with the other responsive rules (this file's last section) rather than beside the chrome base
   above, so the "responsive stays last" rule still holds. */
/* ---- DAY/NIGHT AS A SINGLE ICON BUTTON — EVERY WIDTH WHERE THE HAMBURGER EXISTS ----
   ⚠️ THE BREAKPOINT IS 991.98px, NOT 640px, AND THAT MATTERS. The hamburger is shown from 0 up to
   991px (`.navbar-expand-lg .navbar-toggler { display: none }` starts at 992). Styling the toggle
   only up to 640px left every TABLET width falling back to the DESKTOP rule — `right: 12px` — which
   put it on top of, or right of, the hamburger. Any rule positioning this control must cover the
   same band the button does.
   The desktop control is a SLIDER, and a slider is wide because it has to show travel: 52px, the
   second-widest thing in a 402px bar. Here it becomes one square button showing the CURRENT mode's
   glyph, which is both narrower and a squarer tap target than a 26px-tall rail. Pure CSS — the
   markup already has both glyphs and the checkbox, so deleting this block reverses it entirely. */
@media (max-width: 991.98px) {
   /* Geometry is constant in this band because .navbar > .container is uncapped (see
      punkRevolutions-MainStyles.css): 16px navbar + 15px container = 31px to the hamburger's
      right edge, + its 56px desktop width + a 10px gap = 97px. */
   /* ⚠️ IN THE FLOW HERE, NOT ABSOLUTE — that is the whole point.
      `position: static` turns this into a flex ITEM of .container, sitting beside the hamburger,
      so `.container`'s `align-items: center` centres BOTH against the same line. They are aligned
      by construction; there is nothing left to compute or keep in sync.
      What this replaced: an absolutely-positioned div with a hand-derived `right` offset per
      breakpoint (81 / 64 / 56px, each the sum of two paddings + the button width + a gap) and its
      own `top: 50%` centring. That offset had to be re-derived four separate times as paddings
      and widths changed, and the two centrings agreed only by coincidence — which they stopped
      doing once `.switch`'s inline-block baseline made this div taller than the switch inside it.
      `margin-left: auto` takes over the job the hamburger's own auto-margin was doing: it pushes
      the PAIR right, and the gap between them is this element's margin-right. */
   .navbar-toggler { margin-left: 0; }   /* the toggle carries the auto-margin now */

   /* Compact theme control for the responsive wallet info bar. */
   .switch { width: 34px; height: 34px; }
   .theme-track {
      border-radius: 3px;
      justify-content: center;
      padding: 0;
   }
   .theme-knob { display: none; }                          /* no travel to show with one glyph */
   .theme-track .moon,
   .theme-track .sun {
      font-size: 22px;
      line-height: 1;     /* the glyph's own line-height was the "padding" around it */
   }
   .theme-track .sun { display: none; }                    /* night → moon */
   #darkAndLightModeToggleSwitch:checked ~ .theme-track .moon { display: none; }
   #darkAndLightModeToggleSwitch:checked ~ .theme-track .sun  { display: block; }
}

@media (max-width: 640px) {
   #sheroneBeanieDIV { top: 8px; left: 8px; }
   #BeanieImage { width: 56px; }
   .switch { width: 34px; height: 26px; }
}

@media (max-width: 460px) {
   #sheroneBeanieDIV { top: 4px; left: 0px; }
   #BeanieImage { width: 54px; }
   .switch { width: 30px; height: 24px; }
   .theme-track .moon, .theme-track .sun { font-size: 18px; }
}

/* ⚠️ THE COLLAPSED MENU SITS UNDER THE HAMBURGER, NOT ON THE FAR SIDE OF THE SCREEN.
   `.navbar-nav` carries Bootstrap's `ml-auto`, which right-aligns it only while the navbar is a ROW —
   i.e. on desktop. Collapsed, the list becomes a COLUMN, so `ml-auto` acts on the cross axis and does
   nothing, and each <li> stretches the full width of the bar with its text starting at the left. The
   result read as a menu belonging to the opposite corner from the button that opened it.
   `align-items: flex-end` shrinks each row to its own content and stacks them against the right edge;
   the text-align keeps multi-word links ragged-right to match. The dropdown applies at every width. */
/* ⚠️ REMOVES THE BROWSER'S OWN TAP HESITATION ON THE HAMBURGER. Without `touch-action: manipulation` a
   touch browser may hold a tap back to see whether a second one is coming (double-tap zoom) before
   dispatching it. The viewport meta already suppresses most of that delay on modern browsers, but this
   states it for the element itself and costs nothing. The tap-highlight removal is cosmetic: the button
   has its own pressed styling, and the grey flash reads as lag. */
.navbar-toggler {
   touch-action: manipulation;
   -webkit-tap-highlight-color: transparent;
}




/* ⚠️ HOW FAST THE MENU OPENS AND SHUTS — AND THE ONLY PLACE TO CHANGE IT.
   Bootstrap animates the collapse by transitioning `height` on `.collapsing`, at 0.35s in
   CSS/Bootstrap-CPOLore1155-4.4.1.css (line ~3394). This overrides just the duration; our stylesheet
   loads AFTER Bootstrap's, so it wins without !important.
   ⚠️ IT ALSO RETIMES THE SCRIPT. bootstrap-4.4.1.js reads the duration back off the element
   (Util.getTransitionDurationFromElement) and waits that long before removing `.collapsing` and
   settling the final state — so the CSS number and the JS timing cannot drift apart. Do not "fix" a
   slow menu by editing the vendor file: it is third-party and any edit is lost on upgrade.
   `transition-duration: 0s` removes the animation entirely, if you want it instant. */
.collapsing {
   transition-duration: 0.15s;
}




@media all {
   /* ⚠️ THE OPEN MENU MUST NOT TAKE UP LAYOUT SPACE — THAT IS WHAT MOVED THE LOGO.
      Bootstrap gives .navbar-collapse `flex-basis: 100%`, so when it opens it becomes a full-width flex
      item and WRAPS ONTO ITS OWN ROW inside .navbar > .container. The bar grows to fit it, and the logo,
      which is vertically centred in that bar, slides down with it — the whole header lurched every time
      the hamburger was tapped. Taking the panel out of flow fixes the cause rather than the symptom:
      .navbar is already `position: relative`, so `top: 100%` hangs this just under the bar and `right: 0`
      puts it beneath the button that opened it. The bar's height never changes, so nothing moves.
      `width: auto` lets it shrink to the menu box; the z-index lifts it over the wallet bar below. */
   #navbarSupportedContent.navbar-collapse {
      position: absolute;
      top: 100%;
      right: 5px;
      left: auto;
      width: auto;
      flex-basis: auto;
      z-index: 2500;
   }




   /* The <ul> is what becomes the visible menu box: `width: fit-content` shrinks it to its longest link
      and `margin-left: auto` pushes that box to the right edge, directly under the hamburger. The panel
      it sits in (#navbarSupportedContent) keeps its full-width row — giving IT the background would
      paint a bar across the whole navbar, which is the opposite of a menu hanging off the button. */
   .navbar-collapse .navbar-nav {
      width: 200px;
      /* width: fit-content; */
      margin-left: auto;
      margin-right: 10px;      /* inset the box from the bar's right edge */
      align-items: flex-end;
      background-color: #45454d;
      border: 1px solid #26262b;
      border-radius: 0px;
      padding: 4px 12px;
   }




   /* ⚠️ THIS IS THE ONLY font-size THE NAV LINKS HAVE. Nothing else sets one — not this stylesheet, not
      the Bootstrap file, not the markup siteChrome.js builds — so before this rule they rendered at the
      browser default of 16px, which is simply what they inherited rather than a size anyone chose.
      Tune the menu's type here. The other lever is `.nav-link`'s `padding: 0.5rem 1rem` near the top of
      this file, which sets how tall each row is independently of the type. */
   .navbar-collapse .navbar-nav .nav-link {
      text-align: right;
      letter-spacing: 0.15px;
      font-size: 1.0rem;
   }
}




/* Light mode: both colours above are hardcoded dark-theme values and need their override here — the
   standing rule in CLAUDE.md. Without it the menu stays charcoal on a light page. */
@media all {
   body.daytime .navbar-collapse .navbar-nav {
      background-color: #e6e6ec;
      border-color: #b4b4c0;
   }
}




@media (max-width: 991.98px) {
   #walletInfoWrapperDIV {
      display: flex;
      align-items: center;
      gap: 10px;
      height: auto;
      min-height: 40px;
      padding-right: 7px;
   }




   #walletInfoDIV {
      flex: 1;
      min-width: 0;
      width: auto;
      margin: 0;
      /* ⚠️ ROOM FOR THE "wi" BUTTON. At desktop the bar's text is centred and the absolutely-positioned
         button sits in empty space; here the text is LEFT-aligned and starts at the edge, so without this
         the button would print on top of "CONNECTED WALLET:". Matches left:10px + the button's width. */
      padding-left: 36px;
      padding-right: 0;
      text-align: left;
      white-space: nowrap;
   }




   #walletInfoWrapperDIV .switch { margin: 0; flex-shrink: 0; }




   nav.navbar .navbar-toggler { margin-left: auto; }

   /* ⚠️ THE DESKTOP CONNECT BUTTON IS OFF HERE, AND THE HAMBURGER'S WALLET ICON IS WHY. Below this
      breakpoint the menu button is on screen and its icon connects a wallet already, so this would be a
      second control for one job on the row with the least space on the site. */
   #walletConnectButton { display: none; }
}





@media (max-width: 640px) {
   #walletInfoWrapperDIV {
      min-height: 36px;
      max-height: 40px;
   }
}




@media (max-width: 460px) {
   #walletInfoWrapperDIV {
      min-height: 36px;
      max-height: 40px;
   }




   /* ⚠️ THE PHONE KEEPS THE ORIGINAL MENU BOX — THE FIXED WIDTH IS A DESKTOP CHOICE.
      The all-media block above sets `width: 300px` and `font-size: 1.0rem`, which read well on a
      desktop bar. On a narrow phone 300px plus the 10px right inset is very nearly the whole viewport
      (310 of 320 on the smallest), so the menu stops looking like a panel hanging off the hamburger and
      starts looking like a full-width bar — which is exactly what the note up there says this design is
      not. Below 460px it goes back to shrinking to its longest link.
      ⚠️ THESE TWO VALUES ARE THE PRE-2026-10-03 ONES AND ARE PAIRED WITH THE BLOCK ABOVE. Change the
      width or the type there and decide, deliberately, whether the phone follows. Same specificity, and
      this block is later in the file, which is the only reason it wins. */
   .navbar-collapse .navbar-nav {
      width: 130px;
      margin-right: 5px !important;
      /* width: fit-content; */
   }




   .navbar-collapse .navbar-nav .nav-link {
      font-size: 0.84rem;
   }
}


/* The "cold storage / minting for someone else" explanation lives in the STEP 1 hint-icon
   tooltip now, not in a paragraph above the button: background detail for the few people who
   need it, and as body text it was a wall nobody would read. */




/* ===================== THE PRE-PAID COUPON BANNER — ONE FRAME, TWO PAGES =====================
   🚨 THIS WAS TWO HAND-COPIED COPIES IN TWO PAGE-LOCAL <style> BLOCKS, AND THEY DRIFTED.
   revolutionsMinter.html and editionsMinter.html each carried their own `#couponBannerDIV`, and by
   2026-10-03 they disagreed on six things at once: the dark background (#00156c vs #0a0f24), the light
   background (cream vs pale blue), the width, the heading element, and two different ≤460px rules. That is
   the same failure siteChrome.js was extracted to stop — its own header records two navbars that diverged
   the same way. The frame lives here now; both pages load this file.

   ⚠️ WHAT STAYS PAGE-LOCAL, AND WHY. Only what is genuinely different:
     · revolutionsMinter.html — a fixed `width: 430px`, its ≤460px `width: 90%` override, and the magenta
       <h2> heading. It is the page where a coupon is actually redeemed, so it is the loud one.
     · editionsMinter.html — nothing. On that page a coupon is always a PUNK-OWNER mint, never an edition
       (`mintWithCoupon(punkId, …)` requires the caller to own or be delegated that Punk), so the banner is
       cross-page chrome rather than an offer, and it stays a quiet one-line link. Deliberate, not missing.

   ⚠️ THE PAGE <style> BLOCKS COME AFTER THIS FILE'S <link>, so an equal-specificity page rule wins. That
   is what lets revolutionsMinter.html add its width and heading without !important. Do not reorder.

   ⚠️ COLOURS ARE THE MINT PAGE'S NEWER VALUES, by decision — the editions copy's were the older ones. */
#couponBannerDIV {
   display: block;
   max-width: 920px;
   background: #00156c;
   margin: 18px auto 0 auto;
   padding: 14px 18px;
   border: 1px solid #2b6cff;
   border-radius: 8px;
   color: #7fb0ff;
   font-size: 1.05rem;
   text-align: center;
   text-decoration: none;
   transition: background 0.15s ease, color 0.15s ease;
}




#couponBannerDIV strong { color: #ffffff; letter-spacing: 0.5px; }




#couponBannerDIV:hover { background: #12224a; color: #ffffff; }




/* Light mode: both colours above are hardcoded dark-theme values and need their override here — the
   standing rule in CLAUDE.md. */
body.daytime #couponBannerDIV { background: #fff5de; border-color: #6f7070; color: #1b4fa8; }




body.daytime #couponBannerDIV strong { color: #005df3; }




/* ⚠️ `max-width`, NOT `width` — it has to narrow a banner that has no fixed width (editions) AND one that
   does (the mint page, 430px, which its own page-local rule drops to 90% here). A fixed 430px overflows a
   375px phone, so that override is load-bearing, not cosmetic: copy the width and you must copy it too. */
@media (max-width: 460px) {
   #couponBannerDIV {
      max-width: 90%;
      margin-top: 10px;
   }
}




/* ===================== THE "wi" WALLET-ROLES PANEL — LOCAL DEV ONLY =====================
   A reminder of who each Hardhat test wallet is, hanging off a small button at the far left of the
   wallet bar. wireWalletRolesPanel() in JS/siteChrome.js builds it from /dev-wallet-roles.json, which
   SERVER/siteFiles.js serves in DEVELOPMENT ONLY — so on a published site the button never appears and
   none of this is ever painted.

   ⚠️ POSITIONED LIKE THE HAMBURGER MENU, AND FOR THE SAME REASON. #walletInfoDIV is a flex row whose
   height the bar is sized by; an in-flow panel would push the bar open and shove the page down every
   time it was tapped. Absolute, hanging under its own button, so the bar's height never changes. */
/* ⚠️ ABSOLUTE, NOT A FLEX CHILD, AND THAT IS THE ONLY WAY IT SITS FLUSH LEFT. #walletInfoDIV is
   `text-align: center` with `padding: 5px 12px` at desktop and only becomes a flex row below 992px — so
   a margin on an in-flow button would be centred with the text at desktop and indented by the padding
   everywhere. Taking it out of flow pins it 10px from the screen edge in BOTH layouts, and keeps it from
   shifting the centred "CONNECTED WALLET:" line. Its containing block is #walletInfoWrapperDIV above. */
#walletRolesButton {
   position: absolute;
   left: 10px;
   top: 50%;
   transform: translateY(-50%);
   z-index: 1;
   padding: 1px 7px;
   min-width: 0;
   width: auto;
   font-size: 0.74rem;
   font-weight: 700;
   line-height: 1.5;
   letter-spacing: 0.5px;
   color: #cdeeff;
   background: #1b2a52;
   border: 1px solid #2b6cff;
   border-radius: 4px;
   cursor: pointer;
}




#walletRolesButton:hover { background: #2b6cff; color: #ffffff; }




#walletRolesPanel {
   position: absolute;
   top: 100%;
   left: 10px;   /* flush with the button above it */
   z-index: 2600;          /* above the open hamburger menu's 2500 — whichever was tapped last wins */
   width: max-content;
   max-width: min(680px, 94vw);
   max-height: 70vh;
   overflow-y: auto;
   padding: 10px 14px;
   text-align: left;
   background: #121a30;
   border: 1px solid #2b6cff;
   border-radius: 6px;
   box-shadow: 0 10px 28px rgba(0, 0, 0, 0.55);
   font-size: 0.78rem;
   line-height: 1.5;
   color: #cdeeff;
}




#walletRolesPanel .wrHead {
   font-weight: 700;
   letter-spacing: 0.6px;
   color: #ffffff;
   padding-bottom: 6px;
   border-bottom: 1px solid #2b6cff;
}




#walletRolesPanel .wrHint { font-weight: 400; color: #7fb0ff; letter-spacing: 0; }




#walletRolesPanel .wrGroup {
   margin: 10px 0 4px;
   font-weight: 700;
   color: #9bff5b;
   letter-spacing: 0.4px;
}




/* A three-column grid so the addresses line up in a column that can be read down. */
#walletRolesPanel .wrRow {
   display: grid;
   grid-template-columns: minmax(170px, auto) 108px 1fr;
   gap: 4px 12px;
   align-items: baseline;
   padding: 3px 0;
   border-top: 1px solid rgba(43, 108, 255, 0.22);
}




#walletRolesPanel .wrName { color: #ffffff; }




#walletRolesPanel .wrAddr { font-family: ui-monospace, "Courier New", monospace; color: #7fb0ff; }




#walletRolesPanel .wrPunk {
   display: inline-block;
   margin: 0 4px 2px 0;
   padding: 0 5px;
   border-radius: 3px;
   font-family: ui-monospace, "Courier New", monospace;
   background: rgba(43, 108, 255, 0.18);
}




/* The lane is the thing worth seeing at a glance — ours, a stranger's, sold, or delegated. */
#walletRolesPanel .wrLane-creator   { background: rgba(155, 255, 91, 0.18); color: #c9ffab; }
#walletRolesPanel .wrLane-visitor   { background: rgba(43, 108, 255, 0.22); color: #cdeeff; }
#walletRolesPanel .wrLane-sold      { background: rgba(255, 60, 170, 0.20); color: #ffb6e1; }
#walletRolesPanel .wrLane-delegated { background: rgba(255, 196, 0, 0.18);  color: #ffe08a; }




#walletRolesPanel .wrNone, #walletRolesPanel .wrEmpty { color: #8a8ab0; font-style: italic; }




/* Light mode: every colour above is a hardcoded dark-theme value — the standing rule in CLAUDE.md. */
body.daytime #walletRolesButton {
   color: #1558d6;
   background: #e6ecfb;
   border-color: #6f7070;
}




body.daytime #walletRolesButton:hover { background: #1558d6; color: #ffffff; }




body.daytime #walletRolesPanel {
   background: #ffffff;
   border-color: #6f7070;
   color: #1b1d29;
   box-shadow: 0 10px 28px rgba(0, 0, 0, 0.22);
}




body.daytime #walletRolesPanel .wrHead { color: #0b3a96; }
body.daytime #walletRolesPanel .wrHint { color: #3a4a6a; }
body.daytime #walletRolesPanel .wrGroup { color: #1f7a12; }
body.daytime #walletRolesPanel .wrName { color: #1b1d29; }
body.daytime #walletRolesPanel .wrAddr { color: #3a4a6a; }
body.daytime #walletRolesPanel .wrLane-creator   { background: #e4f7dc; color: #1f5c12; }
body.daytime #walletRolesPanel .wrLane-visitor   { background: #e4ecfb; color: #14306e; }
body.daytime #walletRolesPanel .wrLane-sold      { background: #fde3f1; color: #8a1159; }
body.daytime #walletRolesPanel .wrLane-delegated { background: #fdf0cf; color: #7a5600; }
