/* Explore's controls: the filter button with its badge, the result count with a
   sort beside it, and Load more at the end of the grid. */
#view .explore-actions {
  display: flex;
  justify-content: flex-end;
  margin: -6px 0 10px;
}

#view .explore-badge {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
}

#view .explore-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 4px 0 12px;
  font-size: 14px;
  color: var(--label);
}

#view .explore-count {
  font-weight: 600;
  color: var(--label-2);
}

#view .explore-sort {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
  color: var(--label-2);
}

#view .explore-sort select {
  font-size: 14px;
  font-weight: 600;
  color: var(--label);
}

#view .explore-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 0 4px;
  color: var(--label-2);
}

/* Transaction step sheet. */
.steps { display: flex; flex-direction: column; gap: 2px; margin: 6px 0 14px; }
.step {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 4px;
  min-height: 44px;
}
.step .dot {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  flex: none;
  display: grid;
  place-items: center;
  background: var(--fill);
  color: var(--label-3);
}
.step .dot svg { width: 14px; height: 14px; }
.step .lbl { flex: 1; font-size: 15px; font-weight: 600; }
.step .lbl .sub { display: block; font-size: 12.5px; font-weight: 500; color: var(--label-2); margin-top: 1px; }
.step.doing .dot { background: var(--accent-soft); color: var(--accent); }
.step.doing .lbl { color: var(--accent); }
.step.done .dot { background: rgba(52, 199, 89, 0.14); color: var(--success); }
.step.failed .dot { background: rgba(255, 59, 48, 0.12); color: var(--danger); }
.step.failed .lbl { color: var(--danger); }

.spin {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 2px solid var(--accent-soft-2);
  border-top-color: var(--accent);
  animation: rot 0.75s linear infinite;
}
@keyframes rot { to { transform: rotate(360deg); } }

.hashbox {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--fill);
  font-size: 12.5px;
  color: var(--label-2);
}
.hashbox .mono {
  flex: 1;
  min-width: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.hashbox .copy { color: var(--accent); font-weight: 700; font-size: 13px; flex: none; }

/* ============================================================= utilities */

.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.trunc { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rowlist { display: flex; flex-direction: column; gap: 12px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.pad { padding: 0 20px; }
.mt { margin-top: 16px; }
.center { text-align: center; }

/* Activity row. */
.actrow {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
}

/* Keyframes animations - must be at top level */
@keyframes shimmer {
  from { background-position: 180% 0; }
  to { background-position: -60% 0; }
}

@keyframes rot {
  to { transform: rotate(360deg); }
}
.actrow + .actrow { border-top: 0.5px solid var(--separator); }
.actrow .ai {
  width: 36px;
  height: 36px;
  border-radius: 11px;
  flex: none;
  display: grid;
  place-items: center;
}
.actrow .ai svg { width: 18px; height: 18px; }
.actrow .txt { flex: 1; min-width: 0; }
.actrow .txt .t { font-size: 15px; font-weight: 650; }
.actrow .txt .s { font-size: 12.5px; color: var(--label-2); margin-top: 1px; }
.actrow .when { font-size: 12px; color: var(--label-3); text-align: right; flex: none; }

/* ============================================================ token details
   Mobile-first, and the narrow case is the one designed for: the page is read
   on a phone, one column, thumb-reachable. Everything below the 520px mark is
   the default; the one breakpoint widens it for a desktop browser.

   These were inline `style=` attributes on the token page before. That cannot
   express a media query, so the layout could not change with the width at all —
   the two-column price block and the trait grid were frozen at whatever the
   phone happened to get.                                          */

.details { padding: 0 0 8px; }

/* Full-bleed artwork. Square because the artwork is: a 16:9 crop of a token
   image hides part of what the creator uploaded, and the image is the reason
   most people opened the page. */
.dhero {
  margin: 12px 16px 0;
  border-radius: 22px;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  background: var(--fill);
  box-shadow: var(--shadow-md);
}
.dhero .art { border-radius: 0; height: 100%; }

.dhead { padding: 16px 20px 0; }
.dname {
  margin: 0;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.15;
  overflow-wrap: anywhere;
}
.dbyline {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 7px;
  font-size: 13.5px;
  color: var(--label-2);
}
.dbyline .sep { color: var(--label-3); }
.dchips { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-top: 10px; }

/* Price. Always rendered, listed or not: a block that only appears when there is
   a price makes "not for sale" look like a section that failed to load. */
.dprice {
  margin: 16px 20px 0;
  padding: 14px 16px;
  border-radius: 16px;
  background: var(--fill);
}
.dprice .pl {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--label-2);
}
.dprice .pa {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.dprice .pa.on { color: var(--accent); }
.dprice .pa.off { color: var(--label-3); font-size: 22px; }
.dprice .pa .cur { font-size: 17px; font-weight: 700; color: var(--label-2); margin-left: 3px; }
.dprice .ps { font-size: 13px; color: var(--label-2); margin-top: 3px; }

.dactions { padding: 14px 20px 0; }

/* The two-column hero: the artwork on the left, the token's facts on the
   right. Stacked on a phone, split from 960px up - the item page shape
   marketplace sizes use, with the facts that describe the art beside it. */
.dtwo { display: block; }
.dinfo { min-width: 0; }

/* The market strip under the price: List price / Floor / Floor diff / Top
   offer. Two cells across on a phone, four once there is room, the same grid
   shape the trait cards sit in. */
.dstats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin: 12px 20px 0;
}
.dstat {
  padding: 11px 12px;
  border-radius: 13px;
  background: var(--fill);
  min-width: 0;
}
.dstat-k {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--label-2);
}
.dstat-v {
  font-size: 17px;
  font-weight: 800;
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.dsection { padding: 0 20px; margin-top: 26px; }
.dsection > .dsh {
  font-size: 12px;
  font-weight: 750;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--label-2);
  margin: 0 0 10px;
}
.ddesc {
  font-size: 15px;
  line-height: 1.55;
  color: var(--label);
  margin: 0;
  overflow-wrap: anywhere;
}

/* Traits. Two columns on a phone is the point: four properties fit in two rows
   instead of scrolling past four separate blocks. */
.dtraits {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
.dtrait {
  padding: 11px 12px;
  border-radius: 13px;
  background: var(--fill);
  min-width: 0;
}
.dtrait .tk {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--label-2);
  font-weight: 700;
}
.dtrait .tv {
  font-size: 14.5px;
  font-weight: 750;
  margin-top: 2px;
  overflow-wrap: anywhere;
}

/* The bounds of the activity window. It is a line of its own rather than part
   of a note because it is a fact about the record, not a warning: how far back
   the log reaches changes every time the node's retention window slides. */
.dbounds {
  font-size: 12.5px;
  color: var(--label-2);
  font-variant-numeric: tabular-nums;
  margin: 0 0 10px;
}
.dempty {
  padding: 14px 16px;
  border-radius: 13px;
  background: var(--fill);
  font-size: 14px;
  color: var(--label-2);
}

/* The failed read's raw text. Collapsed by default: it is there so anyone
   checking the failure can see exactly what the node said, and it is not the
   headline. `pre` has to be told to wrap, or a 400-character diagnostic becomes
   one line scrolled off the side of a phone. */
.derror { margin-top: 10px; }
.derror > summary {
  font-size: 12.5px;
  color: var(--label-2);
  cursor: pointer;
  padding: 6px 2px;
}
.derror > pre {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--label-2);
  background: var(--fill);
  border-radius: 12px;
  padding: 11px 12px;
  margin: 0;
}

@media (min-width: 520px) {
  .details { padding-bottom: 20px; }
  .dhero { margin: 16px 24px 0; border-radius: 26px; }
  .dhead { padding: 20px 28px 0; }
  .dname { font-size: 32px; }
  /* The price moves beside the name rather than below it: on a wide screen a
     number stacked under a title is a line the eye crosses to reach. */
  .dprice {
    margin: 18px 28px 0;
    display: flex;
    align-items: baseline;
    gap: 16px;
    flex-wrap: wrap;
  }
  .dprice .ps { margin-top: 0; }
  .dactions { padding: 16px 28px 0; }
  .dsection { padding: 0 28px; }
  .dtraits { grid-template-columns: repeat(4, 1fr); }
  .dstats { grid-template-columns: repeat(4, 1fr); margin: 12px 28px 0; }
}

/* The item page splits into two columns once there is room: the artwork on
   the left, the facts that describe it on the right. The sections below the
   hero keep their full width, so this is a two-lane hero, not a two-column
   page. */
@media (min-width: 960px) {
  .dtwo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 24px;
    align-items: start;
    padding: 0 28px;
  }
  .dtwo .dhero { margin: 16px 0 0; }
  .dtwo .dhead { padding: 4px 0 0; }
  .dtwo .dprice { margin: 16px 0 0; }
  .dtwo .dstats { margin: 12px 0 0; }
  .dtwo .dactions { padding: 14px 0 0; }
}

/* ==================================================== extra pieces used by
   the iOS rebuild: dropzone, collection header, padded cards, tappable rows. */

.pad-card { padding: 16px 16px 18px; }

button.row {
  width: 100%;
  text-align: left;
}

/* The create-page upload area: a local preview only, never stored. */
.dropzone {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 4px;
  cursor: pointer;
}
.dz-preview {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 18px;
  overflow: hidden;
  background: var(--fill);
  /* Dashed border signals "drop zone" — classic upload affordance. */
  border: 2px dashed var(--separator-strong);
  transition: border-color 0.22s ease, background-color 0.22s ease;
}
.dz-preview:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.dz-preview.drag-over {
  border-color: var(--accent);
  background: var(--accent-soft);
  border-style: solid;
  box-shadow: 0 0 0 4px var(--accent-soft);
}
.dz-preview svg,
.dz-preview img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}
/* Upload states colour the whole tile. */
.dz-preview.ok { border-color: var(--success); border-style: solid; background: rgba(52,199,89,0.08); }
.dz-preview.busy { border-color: var(--warning); border-style: solid; background: rgba(245,158,11,0.08); }
.dz-preview.bad { border-color: var(--danger); border-style: solid; background: rgba(255,59,48,0.08); }

/* Placeholder overlay: centered upload icon + label inside the preview tile. */
.dz-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  pointer-events: none;
  color: var(--label-2);
  padding: 20px;
  text-align: center;
}
.dz-placeholder .icon {
  width: 56px;
  height: 56px;
  stroke: currentColor;
  stroke-width: 1.6;
  opacity: 0.55;
}
.dz-placeholder .label {
  font-size: 14px;
  font-weight: 650;
  color: var(--label);
}
.dz-placeholder .hint {
  font-size: 11.5px;
  color: var(--label-3);
  max-width: 80%;
}
.dz-preview:not(.ok):not(.busy):not(.bad) .dz-placeholder { display: flex; }
.dz-preview.ok .dz-placeholder,
.dz-preview.busy .dz-placeholder,
.dz-preview.bad .dz-placeholder,
.dz-preview img + .dz-placeholder { display: none; }

/* The status pill, top-left of the artwork. */
.dz-status {
  position: absolute;
  left: 10px;
  top: 10px;
  padding: 4px 11px;
  border-radius: var(--radius-pill);
  background: var(--label);
  color: #fff;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  box-shadow: var(--shadow-sm);
}
.dz-preview.ok .dz-status { background: var(--success); }
.dz-preview.busy .dz-status { background: var(--warning); }
.dz-preview.bad .dz-status { background: var(--danger); }

.dz-text b { font-size: 14px; }
.dz-text span {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--label-2);
  line-height: 1.45;
}
.dz-preview.ok ~ .dz-text b { color: #1e7a34; }
.dz-preview.bad ~ .dz-text b { color: var(--danger); }

/* Collection page header. */
.collbanner {
  height: 132px;
  border-bottom-left-radius: 26px;
  border-bottom-right-radius: 26px;
}
.colllogo {
  width: 72px;
  height: 72px;
  border-radius: 20px;
  flex: none;
  display: grid;
  place-items: center;
  color: #fff;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.02em;
  box-shadow: var(--shadow-md);
  border: 3px solid #fff;
}

/* ------------------------------------------------ collection items page */
/* The Magic Eden shelf: a header with the owner's name, a stat strip, then a
   tight grid of item cards. The name below is the *owner's* Pi username — a
   collection is an address, and the address sits under the name elided. */

.collhead {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: -34px;
}
.collhead-info {
  min-width: 0;
  padding-top: 34px;
}
.collhead-name {
  margin: 0;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.03em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.collhead-sub {
  margin-top: 3px;
  font-size: 12.5px;
  color: var(--label-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.collstats {
  margin-top: 14px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
  gap: 8px;
}
.collstat {
  min-width: 0;
  padding: 10px 12px;
  background: var(--card);
  border: 0.5px solid var(--separator);
  border-radius: 14px;
  box-shadow: var(--shadow-sm);
}
.collstat b {
  display: block;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: -0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.collstat span {
  display: block;
  margin-top: 3px;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--label-3);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Tighter shelf than the explore grid, one card per little tile. */
.collgrid {
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
}
.mecard .price.last {
  margin-top: 3px;
}
.mecard .price.last .amt {
  color: var(--label-2);
}

