/* glass-tabs.css — per-tab glass + layout for the SPA shell, concatenated
   into ONE request. Sources are glass/<tab>.css. Loads AFTER polish.css so
   these overrides win at equal specificity. Every rule is desktop-scoped. */

/* ======== home ======== */
/* glass/home.css — Home / landing: the glass pass and the desktop layout pass.
 *
 * LOAD ORDER: this file must come AFTER landing.css, featbar.css, intro.css and
 * polish.css (and after glass.css, which defines the tokens it uses). Every rule
 * here is an override layered on top of those sheets; nothing in them is edited.
 *
 * WHAT IS ON THIS TAB, top to bottom:
 *   #gwIntro                 the statement + search + live counter strip (intro.js)
 *   .gw-hero                 the video/wordmark banner            (landing.js)
 *   #gwFeatureBar            the auto-scrolling feature rail      (featbar.js)
 *   .gw-marquee.gw-mono      the two gift belts                   (landing.js)
 *   .gw-slab.gw-wall         the gift wall + #gwWall grid          (landing.js)
 * (market.js trimLanding() removes .gw-xchain, .gw-memes and .gw-outro from the
 *  live home, so this sheet deliberately says nothing about them.)
 *
 * GLASS BUDGET. backdrop-filter re-blurs on every scroll frame, so exactly one
 * surface on this tab gets it: #gwIntro, a single panel that never repeats.
 * Everything that repeats — the five counters, the 32 rail tiles, the 24 wall
 * tiles — gets the blur-free .gw-glass-tile recipe instead: a translucent fill
 * and a lit edge, no compositing layer. The feature rail and the gift belts are
 * animated continuously, so they are kept blur-free too; a backdrop-filter over
 * a moving track re-blurs every frame whether or not the page is scrolling.
 *
 * MOBILE IS UNTOUCHED. Every rule in this file sits inside a min-width media
 * query at 900px or above, so below 900px this sheet contributes no declarations
 * and the phone renders exactly as it did.
 *
 * COLOUR. Only existing tokens: the glass tokens from glass.css and the site
 * palette (--panel, --raised, --well, --hairline, --p300). There is no hardcoded
 * colour anywhere in this file, so the WTF and dark themes both resolve for free.
 */

/* ==========================================================================
   1 · THE DESKTOP SPACING SCALE
   The landing was built section by section, so its rhythm came out as five
   unrelated clamps. These four steps give the tab one scale; every spacing
   override below spends them instead of inventing another number. --gh-col is
   the shared content column, and --gh-gut is the slab padding that makes the
   wall grid land on exactly the same left and right edges as the intro card
   and the hero above it.
   ========================================================================== */
@media (min-width: 900px) {
  #gwLanding {
    --gh-col: 1180px;
    --gh-gut: 24px;
    --gh-s0: 6px;
    --gh-s1: 10px;
    --gh-s2: 16px;
    --gh-s3: 24px;
    --gh-s4: 36px;
    --gh-r-tile: 12px;
    --gh-r-card: 16px;
    --gh-r-slab: 20px;
  }
}

/* ==========================================================================
   2 · #gwIntro — the one real glass surface on this tab
   It was a bare full-width block of text sitting on the page gradient. As a
   bounded panel it gains an edge, reads as the arrival card the sibling sites
   open with, and lines up with the hero and the wall underneath it.
   ========================================================================== */
@media (min-width: 900px) {
  #gwIntro {
    position: relative;
    box-sizing: border-box;
    width: min(var(--gh-col), calc(100% - var(--gh-gut) * 2));
    max-width: none;
    margin: var(--gh-s4) auto var(--gh-s3);
    padding: clamp(22px, 2.2vw, 32px) clamp(22px, 2.4vw, 34px) clamp(20px, 2vw, 28px);
    border-radius: var(--gh-r-slab);
    background: var(--glass-fill);
    border: 1px solid var(--glass-edge);
    box-shadow: var(--glass-shadow);
  }

  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #gwIntro {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  /* No backdrop-filter: an opaque panel, so the statement is never text on air. */
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #gwIntro { background: var(--panel); }
  }

  /* the top light-catch every glass panel in this system has. Absolutely
     positioned on purpose: at >=1200px the card becomes a grid container, and
     an in-flow ::before would take a cell. */
  #gwIntro::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    border-radius: var(--gh-r-slab) var(--gh-r-slab) 0 0;
    background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
    pointer-events: none;
  }

  /* ---- the statement block, on the new scale --------------------------- */
  #gwIntro .gi-line { margin-bottom: var(--gh-s1); }
  #gwIntro .gi-sub  { margin-bottom: var(--gh-s2); font-size: 14px; }

  /* ---- the search, on the glass-input / glass-button recipe ------------- */
  #gwIntro .gi-search { margin-bottom: var(--gh-s3); }
  #gwIntro .gi-input {
    padding: 11px 14px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--well) 70%, transparent);
    border-color: var(--glass-edge);
  }
  #gwIntro .gi-go {
    padding: 11px 22px;
    border-radius: 10px;
  }

  #gwIntro .gi-cap { margin-bottom: var(--gh-s1); }

  /* ---- the counter strip: five blur-free tiles ------------------------- */
  #gwIntro .gi-stats { gap: var(--gh-s1); }
  #gwIntro .gi-stat {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 11px 13px 12px;
    border-radius: var(--gh-r-tile);
    /* the .gw-glass-tile material: translucent fill, lit edge, NO blur */
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border-color: var(--glass-edge);
  }
  /* space-between plus the grid's own stretch puts every figure on one
     baseline across the five tiles, whatever the label above it wrapped to */
  #gwIntro .gi-v { margin-top: var(--gh-s0); }
  /* the help dot was 11px, which is below the size a glyph stays legible at */
  #gwIntro .gi-q {
    width: 13px;
    height: 13px;
    line-height: 13px;
    font-size: 9px;
  }
}

/* ---- >=1200px: the copy and the search share a row ------------------------
   Stacked, the 62ch paragraph and the 620px search each left roughly half the
   card empty to their right. Side by side they fill the card and the counter
   strip still runs the full width underneath, which is the right shape for
   five numbers. Gated at 1200px because the desktop rail takes 264px of the
   viewport and a two-column split below that is cramped. */
@media (min-width: 1200px) {
  #gwIntro {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
    column-gap: clamp(28px, 3vw, 48px);
    align-items: start;
  }
  #gwIntro .gi-line   { grid-column: 1 / -1; grid-row: 1; }
  #gwIntro .gi-sub    { grid-column: 1; grid-row: 2; margin-bottom: 0; }
  #gwIntro .gi-search { grid-column: 2; grid-row: 2; margin: 0; max-width: none; }
  #gwIntro .gi-cap    { grid-column: 1 / -1; grid-row: 3; margin-top: var(--gh-s3); }
  #gwIntro .gi-stats  { grid-column: 1 / -1; grid-row: 4; }
}

/* ==========================================================================
   3 · .gw-hero — the banner, bounded to the shared column
   It was edge to edge while everything under it was a centred 1180px column,
   so the page had two competing left edges. Bounding it to --gh-col and giving
   it the same corner as the intro card puts the whole tab on one grid. The
   wordmark is object-fit:contain and height-constrained here (intro.css), so
   narrowing the box does not shrink the mark.
   ========================================================================== */
@media (min-width: 900px) {
  #gwLanding .gw-hero {
    box-sizing: border-box;
    width: min(var(--gh-col), calc(100% - var(--gh-gut) * 2));
    margin: 0 auto var(--gh-s3);
    border-radius: var(--gh-r-slab);
    border: 1px solid var(--glass-edge);
  }
}

/* ==========================================================================
   4 · #gwFeatureBar — the feature rail
   Kept full bleed on purpose: a masked marquee that runs off both edges reads
   as intentional where a bounded one reads as clipped. Blur-free, because the
   track never stops moving.
   ========================================================================== */
@media (min-width: 900px) {
  #gwFeatureBar { margin: var(--gh-s3) 0 var(--gh-s2); }

  #gwFeatureBar .fb-tile {
    border-radius: var(--gh-r-card);
    /* the .gw-glass-tile material — 32 of these are on screen at once */
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border-color: var(--glass-edge);
  }
  /* the tile's :hover edge is left alone on purpose: featbar.css lights it with
     solid --p400, and that pop is the rail's whole affordance. */

  /* .fb-art carried a hardcoded 200px square while polish.css sets the tile to
     flex:0 0 150px at >=1100px, so the art overflowed its own tile and the
     tile's overflow:hidden cropped a quarter of every image off the right.
     Sizing the art from the tile keeps it square at any tile width. */
  #gwFeatureBar .fb-art {
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
  }

  #gwFeatureBar .fb-label {
    background: color-mix(in srgb, var(--raised) 55%, transparent);
    border-top-color: var(--glass-edge);
  }
}

@media (min-width: 1100px) {
  /* the tiles are 150px here (polish.css), so an 18px gutter between them was
     out of proportion with the tile itself */
  #gwFeatureBar .fb-track { gap: var(--gh-s2); }
}

/* ==========================================================================
   5 · .gw-marquee — the gift belts
   Full bleed and blur-free for the same reason as the rail. Only the two
   hairlines change, so the band's edges match every other edge on the tab.
   ========================================================================== */
@media (min-width: 900px) {
  #gwLanding .gw-marquee {
    border-top-color: var(--glass-edge);
    border-bottom-color: var(--glass-edge);
  }
}

/* ==========================================================================
   6 · .gw-slab.gw-wall — the gift wall
   Two problems at desktop: 104px of padding above and below a single grid, and
   a 68px italic headline sitting under a 34px statement, which read as two
   different pages. The slab padding also drops to --gh-gut so #gwWall lands on
   exactly the same left and right edges as the intro card and the hero.
   ========================================================================== */
@media (min-width: 900px) {
  #gwLanding .gw-slab {
    padding: clamp(44px, 5vw, 72px) var(--gh-gut);
  }
  #gwLanding .gw-slab-head {
    max-width: 860px;
    margin-bottom: clamp(20px, 2.4vw, 32px);
  }
  #gwLanding .gw-kick { margin-bottom: var(--gh-s1); }
  #gwLanding .gw-h2 {
    font-size: clamp(30px, 4.2vw, 50px);
  }
  #gwLanding .gw-lead {
    margin-top: var(--gh-s2);
    font-size: clamp(14px, 1.5vw, 16.5px);
  }

  /* ---- the wall tiles: blur-free, same edge as every other tile -------- */
  #gwLanding .gw-wt { border-color: var(--glass-edge); }
  #gwLanding .gw-wt:hover { border-color: color-mix(in srgb, var(--p300) 55%, transparent); }
}

@media (min-width: 1100px) {
  /* auto-fill was landing on a ragged last row. Six fixed columns divide the
     wall's 24 tiles into four full rows, and every tile stays square because
     .gw-wt already carries aspect-ratio:1/1. */
  #gwLanding .gw-wall-grid {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
}

/* ==========================================================================
   7 · REDUCED TRANSPARENCY
   Anyone who has asked their system for less transparency gets solid surfaces
   instead of a blurred backdrop, matching the block at the end of glass.css.
   ========================================================================== */
@media (min-width: 900px) and (prefers-reduced-transparency: reduce) {
  #gwIntro {
    background: var(--panel) !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  #gwIntro .gi-stat,
  #gwFeatureBar .fb-tile { background: var(--panel); }
  #gwFeatureBar .fb-label { background: var(--raised); }
}

/* ======== gifts ======== */
/* =============================================================================
   glass/gifts.css — glass + desktop layout for the GIFTS tab (the shop grid).

   Covers the surfaces agg.js builds inside #view-gifts:
     the source bar (#aggBar / .agg-bar), the pane header (.agg-whd), the stats
     row (.agg-stats), the composable filter rail (.agg-tools), the aggregated
     grid (#aggGrid / .agg-card) and the on-site buy sheet (.agg-modal).

   In aggregated mode agg.js hides every sibling section of #view-gifts (the
   Hot Now / Hottest Deals / Top Gifts / Tape stack and the in-house #layout
   rail), so those are deliberately NOT styled here: on this tab they are never
   on screen. What a visitor actually sees is the bar, the rail and the grid.

   PURELY ADDITIVE. Nothing in agg.css is rewritten; every declaration here is a
   later-loading override written in longhand so it replaces one property rather
   than a whole shorthand. Load this file AFTER agg.css and AFTER polish.css so
   it wins without !important (the reduced-transparency block at the bottom is
   the one deliberate exception).

   MOBILE IS UNTOUCHED. Every rule lives inside @media (min-width: 900px), so
   below 900px this file contributes zero declarations and phone rendering is
   exactly what it was. Control sizes come down only at 1100px and up, matching
   the breakpoint polish.css already uses for the same reason: a touch target
   wants to stay near 44px, and the oversized controls are a desktop problem.

   THE PERFORMANCE RULE. backdrop-filter forces its own compositing layer and
   re-blurs on every scroll frame, so real glass goes on CHROME ONLY: the source
   bar, the filter rail and the buy sheet. The grid can hold hundreds of cards
   at once, so .agg-card, .agg-stat and the empty state get the blur-free
   .gw-glass-tile recipe instead (translucent fill, lit edge). This file also
   switches OFF the per-card blur that already shipped on .agg-rare and
   .agg-regtag: those chips render once per card, so that blur was paying the
   compositing cost hundreds of times over for a 3px effect nobody can see.

   COLOURS come from the shared palette and the glass tokens only. Every glass
   token is read with a palette fallback (var(--glass-fill, var(--panel))) so
   that if glass.css ever fails to load these surfaces degrade to solid panels
   rather than to transparent, unreadable ones.

   NOT TOUCHED ON PURPOSE: .agg-buy and .agg-btn. The card CTA and the buy-sheet
   actions are being reworked separately, and polish.css already owns their
   desktop scale. The only thing this file does to the buy row is align it to
   the bottom of the card so a row of tiles ends on one line.
   ========================================================================== */

@media (min-width: 900px) {

  /* One spacing scale for the whole tab, so the bar, the stats, the rail and
     the grid step in the same units instead of seven ad-hoc margins.
     --gf-pad repeats the inline padding .agg-wrap already uses, so the chrome
     panels line up edge-for-edge with the grid underneath them. */
  :root {
    --gf-s1: 6px;
    --gf-s2: 10px;
    --gf-s3: 14px;
    --gf-s4: 20px;
    --gf-s5: 28px;
    --gf-pad: clamp(14px, 2.5vw, 40px);
    --gf-radius: 16px;
  }

  /* =========================================================================
     1 · THE SOURCE BAR — real glass. One instance, sits above everything,
     never repeats. Was a full-width flex row with the segment on the left and
     the explanatory sentence pushed to the far right by space-between, which
     on a wide screen left a canyon between them and set the sentence on one
     very long line. It reads as a panel now: controls on the first line, the
     explanation on its own line at a sane measure.
     ====================================================================== */
  .agg-bar {
    position: relative;
    justify-content: flex-start;
    row-gap: var(--gf-s2);
    column-gap: var(--gf-s3);
    margin-top: var(--gf-s3);
    margin-right: var(--gf-pad);
    margin-bottom: 0;
    margin-left: var(--gf-pad);
    padding-top: var(--gf-s3);
    padding-right: var(--gf-s4);
    padding-bottom: var(--gf-s3);
    padding-left: var(--gf-s4);
    border-radius: var(--gf-radius);
    background: var(--glass-fill, var(--panel));
    border: 1px solid var(--glass-edge, var(--hairline-2));
    box-shadow: var(--glass-shadow, 0 10px 34px -14px var(--shadow-card));
  }

  /* the explanation is prose, not a control: give it its own line and a
     readable measure instead of one 2,000px string across an ultrawide. */
  .agg-bar .agg-sub {
    flex: 1 0 100%;
    max-width: 78ch;
    line-height: 1.5;
  }

  /* the segmented control reads as a well cut into the glass */
  .agg-seg {
    background: color-mix(in srgb, var(--well) 72%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
  }

  /* the live count sits with the segment rather than floating mid-canyon */
  .agg-count {
    align-self: center;
  }

  /* =========================================================================
     2 · PANE HEADER — "All gifts" plus its one-line description.
     ====================================================================== */
  .agg-whd {
    margin-top: var(--gf-s5);
    margin-bottom: var(--gf-s1);
    column-gap: var(--gf-s2);
  }
  .agg-wsub {
    max-width: 78ch;
  }

  /* =========================================================================
     3 · STATS — three boxes, so they repeat: flat tile fill, no blur.
     ====================================================================== */
  .agg-stats {
    gap: var(--gf-s2);
    margin-top: var(--gf-s2);
    margin-bottom: var(--gf-s4);
  }
  .agg-stat {
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
    border-radius: 12px;
  }

  /* =========================================================================
     4 · THE FILTER RAIL — real glass. One instance, and the single densest
     piece of chrome on the tab.

     It carries seven labelled groups (Collection, Model, Symbol, Backdrop,
     Price, Colour, Sort). As a wrapping flex row those groups took their
     natural widths, so the controls landed on a ragged edge and the last line
     stretched to fill. As an auto-fit grid every column is the same width and
     the groups line up whatever the viewport, whatever setChain() hides.
     ====================================================================== */
  .agg-tools {
    position: relative;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    align-items: end;
    row-gap: var(--gf-s3);
    column-gap: var(--gf-s2);
    margin-top: 0;
    margin-bottom: var(--gf-s4);
    padding-top: var(--gf-s3);
    padding-right: var(--gf-s4);
    padding-bottom: var(--gf-s3);
    padding-left: var(--gf-s4);
    border-radius: var(--gf-radius);
    background: var(--glass-fill, var(--panel));
    border: 1px solid var(--glass-edge, var(--hairline-2));
    box-shadow: var(--glass-shadow, 0 10px 34px -14px var(--shadow-card));
  }

  /* every control fills its column, so the rail is columns and not confetti */
  .agg-fgroup {
    min-width: 0;
  }
  .agg-tools .agg-sel {
    width: 100%;
    max-width: none;
  }
  .agg-prow {
    gap: var(--gf-s1);
  }
  .agg-tools .agg-num {
    flex: 1 1 0;
    width: auto;
    min-width: 0;
  }
  .agg-tools .agg-toggle {
    width: 100%;
    justify-content: center;
  }

  /* inputs inside glass: a translucent well and the glass edge, so they read as
     cut into the panel rather than pasted onto it. */
  .agg-sel,
  .agg-num,
  .agg-input {
    background: color-mix(in srgb, var(--well) 70%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
    color: var(--ink-hi);
  }
  .agg-sel:focus,
  .agg-num:focus,
  .agg-input:focus {
    outline: none;
    border-color: var(--p300);
    box-shadow: 0 0 0 3px var(--tint-weak);
  }
  /* the Monochrome chip is a control, not an accent, until it is pressed —
     agg.css keeps owning the pressed state. */
  .agg-toggle[aria-pressed="false"] {
    background: color-mix(in srgb, var(--well) 70%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
  }

  /* =========================================================================
     5 · THE GRID — the thing that repeats. No blur anywhere below this line.

     248px minimums gave four very large cards on a 1440px desktop with the
     left rail taking 264px of it. 200px gives five or seven depending on the
     screen, at a size that still carries the art, the name, the price and the
     CTA. More gifts, same card, less dead space.
     ====================================================================== */
  .agg-grid {
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: var(--gf-s3);
  }

  /* the blur-free tile recipe from glass.css, applied to the card itself */
  .agg-card {
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
  }
  .agg-card:hover {
    border-color: color-mix(in srgb, var(--p300) 55%, transparent);
  }
  .agg-art {
    background: color-mix(in srgb, var(--well) 62%, transparent);
  }

  /* EQUAL-HEIGHT TILES. Grid already stretches every card in a row to the same
     height; the bodies did not agree because the regular-gift card carries an
     extra supply line. Letting the body grow and pinning the buy row to its
     bottom makes every CTA in a row land on one line. */
  .agg-body {
    flex: 1 1 auto;
    gap: var(--gf-s1);
  }
  .agg-buyrow {
    margin-top: auto;
  }

  /* THE PER-CARD BLUR, SWITCHED OFF. These two chips ship one backdrop-filter
     each per card; on a 400-card grid that is 400 compositing layers re-blurred
     on every scroll frame for a 3px effect behind a 10px label. A translucent
     panel fill reads the same and costs nothing. It also themes: the old fixed
     dark fill put dark plum ink on a near-black chip in WTF mode. */
  .agg-rare,
  .agg-regtag {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: color-mix(in srgb, var(--panel) 84%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
  }

  /* the empty / loading state fills a grid row, so it gets the tile fill too */
  #aggGrid .agg-note {
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border: 1px solid var(--glass-edge, var(--hairline-2));
    border-radius: 14px;
  }

  /* Load more is chrome, but it sits at the foot of the grid and scrolls with
     it, so it stays blur-free and simply picks up the glass button edge. */
  .agg-more {
    background: color-mix(in srgb, var(--panel) 55%, transparent);
    border: 1px solid var(--glass-edge, var(--hairline-2));
    margin-top: var(--gf-s5);
    transition: background .15s ease, border-color .15s ease;
  }
  .agg-more:hover {
    background: color-mix(in srgb, var(--hover) 75%, transparent);
    border-color: var(--p300);
  }

  /* =========================================================================
     6 · THE BUY SHEET — glass.css already blurs .agg-modal. These are the
     surfaces inside it that were still painting solid against that glass.
     ====================================================================== */
  .agg-mhd {
    border-bottom-color: var(--glass-edge, var(--hairline-2));
  }
  .agg-esc {
    background: color-mix(in srgb, var(--well) 70%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
  }
  .agg-tgnote {
    background: color-mix(in srgb, var(--well) 70%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
  }

  /* =========================================================================
     7 · THE LIGHT-CATCH — the same top sheen .gw-glass-sheen draws, on the two
     panels that are real glass. Absolutely positioned, so it is neither a flex
     item of .agg-bar nor a grid item of .agg-tools.
     ====================================================================== */
  .agg-bar::before,
  .agg-tools::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
    pointer-events: none;
  }

  /* real blur for the two chrome panels, and nothing else on this tab */
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .agg-bar,
    .agg-tools {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  /* no backdrop-filter: solid panels, never transparent unreadable ones */
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .agg-bar,
    .agg-tools {
      background: var(--panel);
    }
  }
}

/* =============================================================================
   8 · DESKTOP CONTROL SCALE — 1100px and up only, the same breakpoint
   polish.css uses. Below it a tablet in landscape is still a touch surface and
   these controls keep their full height.
   ========================================================================== */
@media (min-width: 1100px) {

  .agg-seg-btn {
    padding: 8px 14px;
    font-size: 13px;
  }

  .agg-sel,
  .agg-num {
    padding: 8px 11px;
  }
  .agg-toggle {
    padding: 8px 12px;
  }

  /* the stats box was 24px numerals in a 14x20 box, which out-weighed the
     pane heading above it */
  .agg-stat {
    padding: 11px 15px;
    min-width: 104px;
  }
  .agg-stat-v {
    font-size: 21px;
  }

  /* card interior, at the tighter grid width */
  .agg-body {
    padding: 9px 10px 11px;
  }
  .agg-name {
    font-size: 13px;
  }
  .agg-price b {
    font-size: 15px;
  }

  .agg-more {
    padding: 9px 20px;
    font-size: 12.5px;
  }
}

/* =============================================================================
   9 · REDUCED TRANSPARENCY — some people cannot read text over a busy backdrop.
   glass.css already covers .agg-modal; these are the two panels this file made
   glass. !important here is deliberate: an accessibility preference has to beat
   every layer above, including this one.
   ========================================================================== */
@media (min-width: 900px) and (prefers-reduced-transparency: reduce) {
  .agg-bar,
  .agg-tools {
    background: var(--panel) !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  .agg-card,
  .agg-stat,
  .agg-art,
  .agg-rare,
  .agg-regtag,
  #aggGrid .agg-note {
    background: var(--panel) !important;
  }
}

/* ======== nfts ======== */
/* =============================================================================
   glass/nfts.css — glass + desktop layout for the NFTs tab (#view-nfts).

   PURELY ADDITIVE. Nothing in market.css, nftlanes.css or index.html is edited;
   every declaration here is an override that wins by load order, so this file
   must be linked AFTER nftlanes.css (and after glass.css, whose tokens it uses).

   BELOW 900px THIS FILE CONTRIBUTES ZERO DECLARATIONS. Every rule lives inside
   @media (min-width: 900px), so phone and small-tablet rendering of this tab is
   byte-for-byte what it was. The oversized-control and dead-space problems here
   are desktop problems; shrinking a phone target would trade a real usability
   property for a cosmetic one.

   GLASS BUDGET (see the performance rule at the top of glass.css): exactly two
   surfaces take backdrop-filter, and both are chrome that renders once —
   #nftsHead (the sticky title + chain toggle bar) and #nftsState (the single
   honest empty/offline panel). Everything that REPEATS — the collection tiles,
   the rank badges, the concentration bars — gets the blur-free translucent tile
   fill instead. The tab can paint 100 collections at once, and a per-card
   backdrop-filter re-blurs every one of them on every scroll frame.

   That last point is also a fix, not just a policy: nftlanes.css puts
   backdrop-filter on .nl-rank, which is one badge per card. It is switched off
   here, and the badge's hardcoded near-black fill is replaced with --void so it
   stays readable in the light WTF theme as well as the dark one.

   Colours come from the shared palette tokens only, so both themes work.
   ========================================================================== */

@media (min-width: 900px) {

  /* ---- 1 · THE PAGE FRAME -----------------------------------------------
     The tab was full-bleed, so on a wide monitor the header note floated at
     74ch on the left of a 2,000px band of nothing. A max-width centres the
     board and keeps the head, the panel and the grid on one shared axis. */
  #view-nfts {
    padding-top: 20px;
    padding-bottom: 96px;
  }
  #nftsWrap {
    width: 100%;
    max-width: 1560px;
    margin-left: auto;
    margin-right: auto;
  }

  /* ---- 2 · THE HEAD BAR — real glass, and the tab's only sticky chrome ---
     Title, note and the SOL/ETH toggle share one bar on two aligned columns
     instead of stacking into 90px of dead height. It sticks at 100px, the
     same offset #filters already uses (below the sticky topbar + tab bar), so
     the chain toggle stays reachable while a long board scrolls under it. */
  #nftsHead {
    position: sticky;
    /* 58px, not 100px: 100 was the offset for topbar + #tabbar stacked, but the
       desktop rail hides #tabbar (sidenav.js), so a 100px offset left a ~40px
       band where board rows scrolled visibly under this translucent header.
       #filters was corrected the same way. */
    top: 58px;
    z-index: 6;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 20px;
    row-gap: 4px;
    align-items: center;
    margin-bottom: 18px;
    padding: 14px 18px;
    border: 1px solid var(--glass-edge);
    border-radius: 14px;
    background: var(--glass-fill-strong);
    box-shadow: var(--glass-shadow);
  }
  /* the top light-catch, inset so it follows the rounded corners */
  #nftsHead::before {
    content: "";
    position: absolute;
    inset: 0 12px auto 12px;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
    pointer-events: none;
  }
  #nftsHead h2 {
    grid-column: 1;
    grid-row: 1;
    margin: 0;
    font-size: 18px;
  }
  #nftsNote {
    grid-column: 1;
    grid-row: 2;
    max-width: 70ch;
    font-size: 12.5px;
    line-height: 1.5;
  }

  /* ---- 3 · THE CHAIN TOGGLE — one segmented control ----------------------
     Two loose pills become a single track with a lit selected segment. No
     blur of its own: it sits on the already-blurred head bar, and stacking
     two backdrop-filters costs a second compositing pass for no visible gain. */
  #nftsHead .nl-toggle {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: center;
    margin-top: 0;
    gap: 4px;
    padding: 4px;
    border: 1px solid var(--glass-edge);
    border-radius: 999px;
    background: var(--glass-fill);
  }
  .nl-toggle .nl-chip {
    min-height: 34px;
    padding: 7px 15px;
    border-color: transparent;
    border-radius: 999px;
    background: transparent;
    font-size: 12.5px;
    transition: background .15s ease, color .15s ease;
  }
  .nl-toggle .nl-chip:hover {
    background: color-mix(in srgb, var(--hover) 80%, transparent);
    color: var(--ink-hi);
  }
  .nl-toggle .nl-chip[aria-pressed="true"] {
    background: var(--p400);
    color: var(--on-accent);
    border-color: transparent;
  }
  .nl-toggle .nl-chip:focus-visible {
    outline: 2px solid var(--p400);
    outline-offset: 2px;
  }
  .nl-toggle .nl-chip-tag {
    padding: 1px 5px;
    border-radius: 5px;
    background: color-mix(in srgb, var(--ink-lo) 16%, transparent);
    font-size: 9.5px;
    opacity: .85;
  }
  .nl-toggle .nl-chip[aria-pressed="true"] .nl-chip-tag {
    background: color-mix(in srgb, var(--on-accent) 24%, transparent);
    opacity: 1;
  }

  /* ---- 4 · THE HONEST PANEL ---------------------------------------------
     The static "no cross-chain inventory yet" panel is the one surface that
     has to carry a whole tab on its own, so it gets real glass and a reading
     measure instead of a full-width dashed box with 48px of air in it. */
  #nftsState {
    position: relative;
    max-width: 680px;
    margin: 8px auto 0;
    padding: 34px 32px 30px;
    border: 1px solid var(--glass-edge);
    border-radius: 16px;
    background:
      radial-gradient(120% 140% at 50% 0%, var(--tint-weak), transparent 62%),
      var(--glass-fill-strong);
    box-shadow: var(--glass-shadow);
  }
  #nftsState::before {
    content: "";
    position: absolute;
    inset: 0 14px auto 14px;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
    pointer-events: none;
  }
  #nftsState .gs-title {
    font-size: 16px;
    margin-bottom: 8px;
  }
  #nftsState > div:not(.gs-title) {
    max-width: 52ch;
    font-size: 13.5px;
    line-height: 1.6;
  }
  #nftsToGifts {
    margin-top: 18px;
    padding: 9px 20px;
    border-radius: 10px;
    font-size: 13px;
  }
  #nftsToGifts:focus-visible {
    outline: 2px solid var(--p500);
    outline-offset: 2px;
  }

  /* ---- 5 · THE BOARD ----------------------------------------------------
     align-items was start, which left every row ragged because only some
     collections report a concentration bar. Stretch plus a bottom-anchored
     chip row gives equal-height tiles and one shared baseline per row. */
  #nftsGrid:not([hidden]) {
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: clamp(12px, 1.1vw, 18px);
    align-items: stretch;
    margin-top: 18px;
  }

  /* the repeating tile: translucent fill, NO blur (see the note up top) */
  .nl-card {
    border-radius: 14px;
    border-color: var(--glass-edge);
    background: color-mix(in srgb, var(--panel) 78%, transparent);
  }
  .nl-card .c-body {
    flex: 1 1 auto;
    gap: 6px;
    padding: 11px 12px 12px;
  }
  .nl-card .c-chips {
    margin-top: auto;
    padding-top: 4px;
  }
  .nl-art {
    background: color-mix(in srgb, var(--well) 72%, transparent);
  }
  .nl-mono {
    font-size: 34px;
  }

  /* rank badge: blur removed (it repeats once per card) and the fill moved off
     a hardcoded near-black onto --void, so it reads in both themes. */
  .nl-rank {
    top: 9px;
    left: 9px;
    border: 1px solid var(--glass-edge);
    background: color-mix(in srgb, var(--void) 80%, transparent);
    color: var(--ink-hi);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  /* a fixed stat-row height keeps the concentration bars on one line across
     the row whether or not a collection reports a risk grade */
  .nl-stat {
    min-height: 22px;
    margin-top: 4px;
  }
  .nl-risk {
    flex: 0 0 auto;
  }
  .nl-conc {
    margin-top: 6px;
  }
  .nl-conc-bar {
    height: 6px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--well) 70%, transparent);
  }

  /* ---- 6 · THE FAILURE STATES -------------------------------------------
     Both lane feeds are unreachable today, so this is the state most people
     see. A bare line of 14px grey text in a grid cell reads as a broken page;
     a measured panel reads as a product telling you something. */
  .nl-load {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    max-width: 620px;
    min-height: 220px;
    margin: 0 auto;
    padding: 36px 30px;
    border: 1px dashed var(--glass-edge);
    border-radius: 16px;
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    color: var(--ink-mid);
    font-size: 14px;
    line-height: 1.55;
  }

  /* A lane that answers with zero rows currently paints nothing at all, and a
     grid that collapses to 0px is indistinguishable from a page that failed to
     load. Hold the space and mark it with the no-data glyph. */
  #nftsGrid:not([hidden]):empty {
    grid-template-columns: 1fr;
    place-items: center;
    min-height: 200px;
    border: 1px dashed var(--glass-edge);
    border-radius: 16px;
    background: color-mix(in srgb, var(--panel) 55%, transparent);
  }
  #nftsGrid:not([hidden]):empty::before {
    content: "—";
    color: var(--ink-faint);
    font-size: 30px;
    line-height: 1;
  }

  /* ---- 7 · the two glass surfaces, and their fallbacks ------------------ */
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #nftsHead,
    #nftsState {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  /* no backdrop-filter: solid panels, so a sticky bar never lets cards show
     through it and nothing lands on a transparent background */
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #nftsHead {
      background: var(--panel);
    }
    #nftsState {
      background:
        radial-gradient(120% 140% at 50% 0%, var(--tint-weak), transparent 62%),
        var(--panel);
    }
  }
}

/* ---- 8 · LARGE DESKTOP ---------------------------------------------------
   Past ~1280px there is room to let the tiles breathe rather than fitting one
   more 200px column that nobody asked for. */
@media (min-width: 1280px) {
  #nftsHead {
    padding: 16px 22px;
  }
  #nftsGrid:not([hidden]) {
    grid-template-columns: repeat(auto-fill, minmax(214px, 1fr));
    gap: 18px;
  }
}

/* ---- 9 · REDUCED TRANSPARENCY -------------------------------------------
   Same contract as glass.css: anyone who has asked for less transparency gets
   solid surfaces instead of text over a busy backdrop. */
@media (min-width: 900px) and (prefers-reduced-transparency: reduce) {
  #nftsHead,
  #nftsState {
    background: var(--panel);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  #nftsHead .nl-toggle {
    background: var(--well);
  }
  .nl-card,
  .nl-load {
    background: var(--raised);
  }
  .nl-art,
  .nl-conc-bar {
    background: var(--well);
  }
  .nl-rank {
    background: var(--void);
  }
}

/* ======== launchpad ======== */
/* =============================================================================
   glass/launchpad.css — DESKTOP glass + layout layer for the Launchpad tab.

   Loads AFTER launchpad.css and layers on top of it. Nothing here rewrites an
   existing rule in place: every declaration is an override that wins on source
   order (or on a deliberately equal specificity), so launchpad.css stays the
   single source of truth for the base look.

   SCOPE: every rule in this file lives inside `@media (min-width: 900px)` or
   wider. Below 900px the Launchpad renders exactly as it did before, including
   the stacked single-column wizard and its 16px touch-sized inputs.

   MATERIAL: the tokens and the two-tier treatment come from glass.css.
     - real glass (blur) on CHROME only: the progress rail, the wizard footer,
       the preview bar, the layout-designer modal and the success overlay.
     - repeating things (template cards, example art, block rows, file rows,
       cost cards, chips, small buttons) get the blur-free `.gw-glass-tile`
       treatment: a translucent fill and a lit edge, no backdrop-filter. There
       can be dozens of them on screen at once and backdrop-filter would put a
       compositing layer on every one.

   The `--lp-glass-*` locals below are NOT a second palette: each one resolves
   to the matching glass.css token and only falls back to that token's own
   definition if glass.css has not been linked yet, so a missing <link> degrades
   to the same material instead of to a transparent, unreadable panel.
   ========================================================================== */

@media (min-width: 900px) {

  /* -------------------------------------------------------------------------
     1 · ONE SCALE — spacing, radius and the resolved glass material.
     Declared on .lp-root, which is also the parent of both overlays.
     ---------------------------------------------------------------------- */
  .lp-root {
    --lp-pad: 24px;
    --lp-gap: 16px;
    --lp-gap-s: 10px;
    --lp-r: 12px;
    --lp-r-lg: 16px;
    --lp-nav-h: 86px;
    --lp-bar-h: 44px;

    --lp-glass-fill: var(--glass-fill, color-mix(in srgb, var(--panel) 62%, transparent));
    --lp-glass-fill-strong: var(--glass-fill-strong, color-mix(in srgb, var(--panel) 84%, transparent));
    --lp-glass-edge: var(--glass-edge, var(--hairline-2));
    --lp-glass-sheen: var(--glass-sheen, color-mix(in srgb, #fff 12%, transparent));
    --lp-glass-shadow: var(--glass-shadow, 0 10px 34px -14px var(--shadow-card));
    --lp-glass-blur: var(--glass-blur, 16px);
    --lp-glass-sat: var(--glass-sat, 165%);

    /* mirrors .gw-glass-tile / .gw-glass-btn from glass.css — no blur, on purpose */
    --lp-tile: color-mix(in srgb, var(--panel) 78%, transparent);
    --lp-btn: color-mix(in srgb, var(--panel) 55%, transparent);
  }

  /* -------------------------------------------------------------------------
     2 · SHELL — both panes become positioning contexts so their chrome can
     float over the scrolling content instead of stealing a band from it.
     ---------------------------------------------------------------------- */
  .lp-designer {
    position: relative;
    padding: var(--lp-pad) var(--lp-pad) 0;
  }
  .lp-preview { position: relative; }

  /* -------------------------------------------------------------------------
     3 · CHROME — real glass. Four surfaces, and only four.
     ---------------------------------------------------------------------- */

  /* progress rail */
  .lp-rail {
    position: relative;
    margin: 10px 0 14px;
    padding: 12px 15px;
    border-radius: var(--lp-r-lg);
    background: var(--lp-glass-fill);
    border: 1px solid var(--lp-glass-edge);
    box-shadow: var(--lp-glass-shadow);
  }

  /* wizard footer: full-bleed to the pane gutter (it used to sit 2px inside it)
     and the step body now scrolls underneath it */
  .lp-nav {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 4;
    margin: 0;
    padding: 14px var(--lp-pad);
    background: var(--lp-glass-fill-strong);
    border-top: 1px solid var(--lp-glass-edge);
    box-shadow: 0 -12px 30px -24px var(--shadow-card);
  }
  .lp-steps {
    padding-bottom: var(--lp-nav-h);
    scrollbar-gutter: stable;
  }

  /* preview bar: floats over the device canvas, which reclaims its whole band */
  .lp-preview-bar {
    position: absolute;
    top: 0; left: 0; right: 0;
    z-index: 3;
    padding: 8px 18px;
    background: var(--lp-glass-fill-strong);
    border-bottom: 1px solid var(--lp-glass-edge);
  }
  .lp-preview-scroll {
    padding: calc(var(--lp-bar-h) + 16px) 20px 30px;
  }

  /* layout-designer modal + its scrim */
  .lp-dz-back { background: color-mix(in srgb, var(--void) 62%, transparent); }
  .lp-dz {
    position: relative;
    background: var(--lp-glass-fill-strong);
  }
  .lp-dz-foot { background: color-mix(in srgb, var(--panel) 55%, transparent); }
  .lp-dz-right { background: color-mix(in srgb, var(--well) 55%, transparent); }

  /* success overlay + its scrim */
  .lp-success-back { background: color-mix(in srgb, var(--void) 66%, transparent); }
  .lp-success {
    position: relative;
    background: var(--lp-glass-fill-strong);
  }

  /* the top light-catch every real glass surface here carries */
  .lp-rail::before,
  .lp-nav::before,
  .lp-preview-bar::before,
  .lp-dz::before,
  .lp-success::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--lp-glass-sheen) 22%, var(--lp-glass-sheen) 78%, transparent);
    pointer-events: none;
  }

  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .lp-rail,
    .lp-nav,
    .lp-preview-bar {
      -webkit-backdrop-filter: blur(var(--lp-glass-blur)) saturate(var(--lp-glass-sat));
      backdrop-filter: blur(var(--lp-glass-blur)) saturate(var(--lp-glass-sat));
    }
    .lp-dz,
    .lp-success {
      -webkit-backdrop-filter: blur(22px) saturate(var(--lp-glass-sat));
      backdrop-filter: blur(22px) saturate(var(--lp-glass-sat));
    }
    .lp-dz-back,
    .lp-success-back {
      -webkit-backdrop-filter: blur(8px);
      backdrop-filter: blur(8px);
    }
  }

  /* No backdrop-filter: go solid so nothing lands on a see-through panel. */
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .lp-rail,
    .lp-nav,
    .lp-preview-bar,
    .lp-dz,
    .lp-success { background: var(--panel); }
  }

  /* -------------------------------------------------------------------------
     4 · REPEATING SURFACES — flat tile fill, deliberately blur-free.
     Selected-state and hover rules in launchpad.css are two-class selectors,
     so they still win over these single-class fills.
     ---------------------------------------------------------------------- */
  .lp-tpl,
  .lp-ex-cell,
  .lp-dz-row,
  .lp-dz-add,
  .lp-dz-preset,
  .lp-md-card,
  .lp-md-file,
  .lp-md-attr,
  .lp-rv-tier,
  .lp-rv-summary,
  .lp-gen-jcard,
  .lp-fund,
  .lp-presale-box,
  .lp-meme-box,
  .lp-drop,
  .lp-seg,
  .lp-dz-settings {
    background: var(--lp-tile);
    border-color: var(--lp-glass-edge);
  }
  /* cost cards keep their own accent borders, so only the fill is layered on */
  .lp-cost { background: var(--lp-tile); }

  /* small repeating buttons share one translucent chip fill */
  .lp-mini-btn,
  .lp-file-btn,
  .lp-copy,
  .lp-nav-back,
  .lp-tier-rm,
  .lp-dz-rowbtn,
  .lp-dz-x,
  .lp-dz-cancel {
    background: var(--lp-btn);
    border-color: var(--lp-glass-edge);
  }

  /* -------------------------------------------------------------------------
     5 · SPACING RHYTHM — one 16 / 10 scale instead of 6 / 8 / 12 / 14 mixed.
     ---------------------------------------------------------------------- */
  .lp-head { margin-bottom: 12px; }
  .lp-lede { max-width: 46ch; }
  .lp-sec-b { gap: var(--lp-gap); }
  .lp-grid2,
  .lp-colors,
  .lp-uploads,
  .lp-templates { gap: var(--lp-gap); }
  .lp-tiers { gap: var(--lp-gap-s); }
  .lp-review { gap: var(--lp-gap); }
  .lp-md-summary,
  .lp-md-assets { gap: var(--lp-gap-s); }
  .lp-costs { gap: var(--lp-gap); }
  .lp-designcta { margin-top: var(--lp-gap); }

  /* radius rhythm: 12 for controls, 16 for panels */
  .lp-input,
  .lp-url-link,
  .lp-copy { border-radius: var(--lp-r); }
  .lp-tpl,
  .lp-cost,
  .lp-md-card,
  .lp-gen-jcard,
  .lp-fund,
  .lp-presale-box,
  .lp-meme-box,
  .lp-drop,
  .lp-rv-summary,
  .lp-rv-explain,
  .lp-dz-settings,
  .lp-designbtn { border-radius: var(--lp-r-lg); }

  /* -------------------------------------------------------------------------
     6 · EQUAL-HEIGHT TILES — rows line up across a set even when one card's
     caption wraps to a second line.
     ---------------------------------------------------------------------- */
  .lp-tpl {
    display: grid;
    grid-template-rows: auto auto 1fr;
    gap: 8px;
  }
  .lp-cost {
    display: grid;
    grid-template-rows: auto auto 1fr;
    gap: 4px;
  }

  /* -------------------------------------------------------------------------
     7 · ALIGNED COLUMNS
     ---------------------------------------------------------------------- */
  .lp-rv-row { grid-template-columns: 140px minmax(0, 1fr) auto; }
  .lp-tier { gap: var(--lp-gap-s); }
  .lp-dz-body { grid-template-columns: minmax(0, 1fr) 340px; }
  .lp-color-row { grid-template-columns: 40px minmax(0, 1fr) 18px; }

  /* -------------------------------------------------------------------------
     8 · TIGHTER CONTROLS — the wizard is a dense desktop form, not a phone.
     ---------------------------------------------------------------------- */
  .lp-input { padding: 9px 12px; font-size: 13.5px; }
  /* re-stated after .lp-input so the bulk-tier row keeps its compact cells */
  .lp-tier-qty,
  .lp-tier-disc { padding: 8px 10px; font-size: 13px; }
  .lp-color-in { width: 40px; height: 36px; }
  .lp-seg-btn { padding: 7px 16px; }
  .lp-view-btn { padding: 4px 10px; }
  .lp-mini-btn { padding: 6px 11px; }
  .lp-drop-inner { padding: 18px 14px; }
  .lp-nav-back { padding: 11px 16px; font-size: 13px; }
  .lp-nav-next { padding: 12px 22px; font-size: 13.5px; }
  .lp-designbtn { padding: 13px 16px; font-size: 14.5px; }
  .lp-success-close { padding: 11px; }
  .lp-dz-x { width: 32px; height: 32px; }
  .lp-dz-done { padding: 10px 20px; }
  .lp-dz-cancel { padding: 10px 16px; }
}

/* ===========================================================================
   9 · WIDE DESKTOP — give the form room without starving the preview.
   ======================================================================== */
@media (min-width: 1280px) {
  .lp-root { grid-template-columns: minmax(400px, 500px) 1fr; }
  .lp-preview-scroll { padding-left: 28px; padding-right: 28px; }
  .lp-dz { max-width: 1120px; }
  .lp-dz-body { grid-template-columns: minmax(0, 1fr) 360px; }
}

@media (min-width: 1600px) {
  .lp-root { grid-template-columns: minmax(440px, 560px) 1fr; }
  /* only when the desktop device is the sole thing on the canvas — the "Both"
     view still needs the narrower window so the phone sits beside it */
  .lp-devices[data-view="desktop"] .lp-dev-desktop { max-width: 900px; }
}

/* ===========================================================================
   10 · REDUCED TRANSPARENCY — some people cannot read over a busy backdrop.
   ======================================================================== */
@media (min-width: 900px) and (prefers-reduced-transparency: reduce) {
  .lp-rail,
  .lp-nav,
  .lp-preview-bar,
  .lp-dz,
  .lp-success {
    background: var(--panel) !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  .lp-dz-back,
  .lp-success-back {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  .lp-tpl,
  .lp-ex-cell,
  .lp-dz-row,
  .lp-dz-add,
  .lp-dz-preset,
  .lp-md-card,
  .lp-md-file,
  .lp-md-attr,
  .lp-rv-tier,
  .lp-rv-summary,
  .lp-gen-jcard,
  .lp-fund,
  .lp-presale-box,
  .lp-meme-box,
  .lp-drop,
  .lp-seg,
  .lp-dz-settings,
  .lp-cost { background: var(--panel); }
  .lp-mini-btn,
  .lp-file-btn,
  .lp-copy,
  .lp-nav-back,
  .lp-tier-rm,
  .lp-dz-rowbtn,
  .lp-dz-x,
  .lp-dz-cancel { background: var(--raised); }
  .lp-dz-foot { background: var(--panel); }
  .lp-dz-right { background: var(--well); }
}

/* ======== stats ======== */
/* =============================================================================
   glass/stats.css — glass + desktop layout for the Stats tab (#view-stats).

   PURELY ADDITIVE. This sheet must load AFTER market.css, stats-normie.css and
   polish.css; it layers overrides on top of them and rewrites nothing in place.

   MOBILE IS UNTOUCHED. Every declaration in this file lives inside a
   (min-width: 900px) query, so below 900px the file contributes zero
   declarations and phone rendering is byte-for-byte what it was.

   WHAT GETS REAL GLASS, AND WHY
   The tab has a short list of single-instance surfaces, and only those get a
   backdrop-filter:
     · .sx-pulse        the market-pulse band, one per page
     · #compareBar      the pinned cross-chain compare panel, one per page
     · .im-inlay        the holder-map compare shell, one per page
     · #statsTable thead th   a sticky header, the classic glass case
     · #statsState / #imInlayNote   single-instance empty-state panels
   Nothing in that list repeats.

   WHAT STAYS FLAT
   The four .sx-stat pulse tiles, the eight .sx-card trending cards, every
   #statsBody row, every .im-cl-row cluster row and every compare-table cell
   repeat. They get the blur-free treatment from .gw-glass-tile in glass.css:
   a translucent fill plus a lit edge, same family look, no compositing layer
   per item. See the performance rule at the top of glass.css.

   The markup carries no .gw-glass* classes (market.js builds the pulse band and
   the trending cards, and a second agent owns this tab's JavaScript), so the
   shared material is applied here through the same tokens those classes use.
   Blur values, fills, edges and shadows all come from glass.css; every colour
   comes from the site palette tokens, so both the WTF pastel and the dark theme
   resolve without a second palette.

   ONE NOTE ON THE NUMBERS
   The pulse counters are summed from the gifts_only collections lane, which is
   a narrower set than the Gifts tab's universe. That disagreement is real and
   deliberate. This sheet does not touch a single figure; it only gives the
   scope line under the title (.sx-pulse-sub) room to be read.
   ========================================================================== */

@media (min-width: 900px) {

  /* ---- 1. ONE SPACING SCALE FOR THE WHOLE TAB --------------------------
     The view mixed four rhythms: a 4/16px pulse margin, a 14px movers margin,
     a 2/14px toggle margin and the inlay's own 20px. One scale, declared on
     the view so every block below inherits it. */
  #view-stats {
    --sx-gap: 24px;      /* gutter between the tab's major blocks          */
    --sx-tile-gap: 14px; /* gutter inside every grid on the tab            */
    --sx-pad: 20px;      /* interior padding of a glass panel              */
    --sx-radius: 16px;   /* panel radius; tiles sit 4px tighter            */
  }

  /* ---- 2. THE MARKET PULSE BAND — real glass ---------------------------
     One element, sitting over the scrolling page, so it earns its layer. The
     two branded radial tints are kept but re-pointed at the palette: the
     original second tint resolved to a hardcoded blue because --acc is not
     defined on this page, which read as an off-palette wash in both themes. */
  #view-stats .sx-pulse {
    margin: 0 0 var(--sx-gap);
    padding: var(--sx-pad) var(--sx-pad) 18px;
    border-radius: var(--sx-radius);
    background:
      radial-gradient(120% 120% at 0% 0%, color-mix(in srgb, var(--p400) 14%, transparent), transparent 60%),
      radial-gradient(120% 120% at 100% 100%, color-mix(in srgb, var(--p300) 14%, transparent), transparent 62%),
      var(--glass-fill-strong);
    border: 1px solid var(--glass-edge);
    box-shadow: var(--glass-shadow);
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #view-stats .sx-pulse {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #view-stats .sx-pulse { background: var(--panel); }
  }
  /* the top light-catch every real glass panel has (glass.css .gw-glass-sheen).
     .sx-pulse is already position:relative + overflow:hidden and has no other
     pseudo-element, so this is a clean addition. */
  #view-stats .sx-pulse::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
    pointer-events: none;
  }

  /* the pulse title row: title, then the scope line, on one baseline */
  #view-stats .sx-pulse-h { margin-bottom: 16px; gap: 10px; flex-wrap: wrap; }
  #view-stats .sx-pulse-sub { margin-left: auto; text-align: right; }

  /* ---- 3. THE FOUR PULSE COUNTERS — flat tiles, equal height -----------
     They were bare padding on a shared background, so four figures of very
     different length read as a ragged row. The .gw-glass-tile recipe gives
     each one a box; the grid gives them equal width and equal height. */
  #view-stats .sx-pulse-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--sx-tile-gap);
  }
  /* deliberately NOT bottom-aligned: the figures are what a reader scans, so
     they stay on one line at the top and a label that wraps grows downward. */
  #view-stats .sx-stat {
    display: flex;
    flex-direction: column;
    padding: 14px 15px 12px;
    border-radius: 12px;
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border: 1px solid var(--glass-edge);
  }
  /* 3.4vw put this at 32px on a wide monitor, which crowded a four-up row.
     Tie it to a gentler slope so the label still reads as the same size. */
  #view-stats .sx-stat-n { font-size: clamp(22px, 2.1vw, 29px); }
  #view-stats .sx-stat-k { margin-top: 7px; }
  #view-stats .sx-stat-k .sx-q { margin-left: 1px; }

  /* ---- 4. THE HOTTEST-COLLECTION CALLOUT — flat, inside the glass ------
     Nested backdrop-filters cost a second layer and buy nothing, so this one
     takes the tile fill. */
  #view-stats .sx-hot {
    margin-top: 18px;
    padding: 12px 14px;
    gap: 14px;
    border-radius: 14px;
    background: color-mix(in srgb, var(--p400) 10%, color-mix(in srgb, var(--panel) 70%, transparent));
    border: 1px solid color-mix(in srgb, var(--p400) 26%, transparent);
  }
  #view-stats .sx-hot-kick { letter-spacing: .12em; }
  #view-stats .sx-hot-name { font-size: 15.5px; }

  /* ---- 5. TRENDING CARDS — repeating, so blur-free ---------------------
     Eight cards. auto-fill at minmax(232px) landed on six narrow columns at
     1600px and a ragged 6+2 tail; four fixed columns give two clean rows of
     four on any real desktop, and every card aligns with the one beside it. */
  #view-stats .sx-movers { margin: 0 0 var(--sx-gap); }
  #view-stats .sx-movers-h { margin: 0 2px 14px; gap: 12px; }
  #view-stats .sx-movers-t { font-size: 15px; }
  #view-stats .sx-grid {
    grid-template-columns: repeat(auto-fill, minmax(238px, 1fr));
    gap: var(--sx-tile-gap);
  }
  #view-stats .sx-card {
    padding: 15px;
    gap: 11px;
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border: 1px solid var(--glass-edge);
    box-shadow: 0 2px 10px -6px var(--shadow-card);
  }
  #view-stats .sx-card:hover {
    border-color: color-mix(in srgb, var(--p300) 55%, transparent);
    box-shadow: 0 14px 30px -14px var(--shadow-card);
  }
  #view-stats .sx-c-figs { gap: 18px; }
  /* the concentration gauge is the card's payload, and a card with no gauge
     printed a single line where the others printed two, so the call-to-action
     under it sat 13px higher. A floor height lines every gauge up. */
  #view-stats .sx-conc {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-height: 34px;
  }
  #view-stats .sx-c-cta {
    padding-top: 11px;
    border-top: 1px solid var(--glass-edge);
  }

  /* ---- 6. THE DEEP-DIVE TOGGLE — a glass pill, tightened ---------------
     A 12.5px label in 9px/15px padding is a landing-page-sized control on a
     row of its own. Desktop only, so no touch target shrinks. */
  #view-stats .sx-deep-toggle {
    margin: 0 0 20px;
    padding: 8px 15px;
    font-size: 12px;
    background: color-mix(in srgb, var(--panel) 55%, transparent);
    border: 1px solid var(--glass-edge);
    border-radius: 10px;
  }
  #view-stats .sx-deep-toggle:hover {
    background: color-mix(in srgb, var(--hover) 75%, transparent);
    border-color: var(--p300);
  }

  /* ---- 7. THE HOLDER-MAP COMPARE INLAY ---------------------------------
     Real glass on the shell (one element). The header band keeps its tint and
     gains the light-catch as an inset highlight, so no pseudo-element is
     added to markup another agent owns. */
  #imStatsInlay {
    --sx-map-h: clamp(420px, 44vh, 540px);
    margin-bottom: var(--sx-gap);
  }
  #imStatsInlay .im-inlay {
    border-radius: var(--sx-radius);
    background:
      radial-gradient(120% 140% at 50% -10%, var(--tint-weak), transparent 60%),
      var(--glass-fill-strong);
    border: 1px solid var(--glass-edge);
    box-shadow: var(--glass-shadow);
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #imStatsInlay .im-inlay {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #imStatsInlay .im-inlay { background: var(--panel); }
  }
  #imStatsInlay .im-ih {
    padding: 12px 16px;
    border-bottom: 1px solid var(--glass-edge);
    box-shadow: inset 0 1px 0 var(--glass-sheen);
  }
  /* the two collection pickers were capped at 160px, which truncated most
     collection names; the row has the width, so give it to them. */
  #imStatsInlay .im-sel {
    max-width: 200px;
    padding: 6px 10px;
    background: color-mix(in srgb, var(--well) 70%, transparent);
    border: 1px solid var(--glass-edge);
  }
  #imStatsInlay .im-wbtn {
    padding: 6px 11px;
    font-size: 11.5px;
    background: color-mix(in srgb, var(--panel) 55%, transparent);
    border: 1px solid var(--glass-edge);
  }
  #imStatsInlay .im-wbtn:hover { border-color: var(--p300); }
  /* the drawer and the maps were two independent fixed heights that only
     happened to match. Bind both to one value so the columns stay flush. */
  #imStatsInlay .im-maps { height: var(--sx-map-h); }
  #imStatsInlay .im-drawer {
    max-height: var(--sx-map-h);
    border-right: 1px solid var(--glass-edge);
    background: color-mix(in srgb, var(--well) 82%, transparent);
  }
  #imStatsInlay .im-cl-h { padding: 13px 15px 9px; }
  #imStatsInlay .im-cl-row { padding: 9px 15px; border-top-color: var(--glass-edge); }
  #imStatsInlay .im-cl-empty { padding: 16px 15px; }
  /* the honest-empty note is a single panel, so it can carry the material */
  #view-stats #imInlayNote {
    margin-bottom: var(--sx-tile-gap);
    padding: 20px 18px;
    border-radius: 14px;
    background: var(--glass-fill);
    border: 1px dashed var(--glass-edge);
  }
  #imStatsInlay .im-vs { margin-top: var(--sx-tile-gap); }
  #imStatsInlay .im-vs-table {
    border-radius: 12px;
    background: color-mix(in srgb, var(--panel) 82%, transparent);
    border: 1px solid var(--glass-edge);
  }
  #imStatsInlay .im-vs-table th,
  #imStatsInlay .im-vs-table td { padding: 10px 15px; }
  #imStatsInlay .im-vs-colh { min-width: 150px; }
  #imStatsInlay .im-vs-cname { max-width: 180px; }

  /* ---- 8. STATS HEADER + HONEST EMPTY STATE ---------------------------- */
  #view-stats #statsHead { margin-bottom: 16px; }
  #view-stats #statsHead h2 { font-size: 18px; margin-bottom: 5px; }
  #view-stats #statsNote { max-width: 74ch; line-height: 1.55; }
  #view-stats #statsState {
    padding: 34px 22px;
    border-radius: var(--sx-radius);
    background: var(--glass-fill);
    border: 1px dashed var(--glass-edge);
    box-shadow: var(--glass-shadow);
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #view-stats #statsState {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #view-stats #statsState { background: var(--panel); }
  }
  #view-stats #statsState .gs-title { margin-bottom: 6px; font-size: 15px; }

  /* ---- 9. THE CROSS-CHAIN COMPARE PANEL — real glass ------------------- */
  #view-stats #compareBar {
    margin-bottom: var(--sx-gap);
    padding: 16px 18px;
    border-radius: var(--sx-radius);
    background: var(--glass-fill-strong);
    border: 1px solid color-mix(in srgb, var(--p500) 55%, var(--glass-edge));
    box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-sheen);
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #view-stats #compareBar {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #view-stats #compareBar { background: var(--panel); }
  }
  #view-stats #compareHead { margin-bottom: 6px; }
  #view-stats #cmpNote { margin-bottom: 12px; line-height: 1.5; }
  #view-stats #cmpClear { padding: 4px 10px; border-radius: 8px; }
  #view-stats .cmp-table th,
  #view-stats .cmp-table td { padding: 9px 15px; }
  #view-stats .cmp-colh { min-width: 140px; }
  #view-stats .cmp-cname { max-width: 170px; }
  /* .cmp-rowh is the sticky left column: it has to stay opaque or the cells
     scrolling under it would read through. Only its edge is restyled. */
  #view-stats .cmp-rowh { border-right: 1px solid var(--glass-edge); }

  /* ---- 10. THE FULL TABLE — flat surface, glass sticky header ----------
     #statsTableWrap already computed to a scroll container (overflow-x:auto
     makes overflow-y auto too), which meant the sticky thead had a scrollport
     as tall as the table and never actually stuck. Giving the wrap a real
     height turns 39 rows into a bounded, scannable board and makes the sticky
     header do its job, instead of adding roughly 1,500px of page to scroll
     past. */
  #view-stats #statsTableWrap {
    max-height: min(70vh, 720px);
    overflow: auto;
    border-radius: var(--sx-radius);
    border: 1px solid var(--glass-edge);
    background: color-mix(in srgb, var(--panel) 82%, transparent);
  }
  #view-stats #statsTable {
    background: transparent;
    border: 0;
    border-radius: 0;
  }
  #view-stats #statsTable thead th {
    padding: 11px 15px;
    background: var(--glass-fill-strong);
    border-bottom: 1px solid var(--glass-edge);
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #view-stats #statsTable thead th {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #view-stats #statsTable thead th { background: var(--raised); }
  }
  #view-stats #statsTable tbody td { padding: 10px 15px; }
  #view-stats .st-col { min-width: 200px; }
  #view-stats .st-who { gap: 10px; }
  #view-stats .st-who img { width: 24px; height: 24px; border-radius: 6px; }
  #view-stats .st-cmp { width: 44px; }
  #view-stats .st-check { border-color: var(--glass-edge); }
  #view-stats .st-unit { font-size: 10.5px; }
  #view-stats .st-miss { font-weight: 500; }

  /* ---- 11. REDUCED TRANSPARENCY -----------------------------------------
     Same contract as glass.css: anyone who asks for less transparency gets
     solid surfaces instead of text over a busy backdrop. */
  @media (prefers-reduced-transparency: reduce) {
    #view-stats .sx-pulse,
    #view-stats #compareBar,
    #view-stats #statsState,
    #view-stats #statsTable thead th,
    #imStatsInlay .im-inlay {
      background: var(--panel) !important;
      -webkit-backdrop-filter: none !important;
      backdrop-filter: none !important;
    }
    #view-stats .sx-stat,
    #view-stats .sx-card,
    #view-stats #statsTableWrap,
    #imStatsInlay .im-vs-table { background: var(--panel); }
    #imStatsInlay .im-drawer { background: var(--well); }
  }
}

/* =============================================================================
   WIDE DESKTOP — 1360px and up. The side rail (264px, from 1100px) is already
   accounted for: at 1360px the content column is about 1,016px, which is where
   four trending cards stop being cramped.
   ========================================================================== */
@media (min-width: 1360px) {
  /* eight cards, two clean rows of four, every gauge on the same line */
  #view-stats .sx-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* the cluster drawer can afford the width a wallet row actually needs */
  #imStatsInlay .im-inlay-grid { grid-template-columns: 272px 1fr; }
  #view-stats .sx-card { padding: 16px; }
  #view-stats .sx-pulse { padding: 22px 22px 20px; }
}

/* =============================================================================
   VERY WIDE — cap the measure. market.css runs this view full-bleed on purpose
   so the seven-column table can breathe, and that holds up to about 1,500px of
   content. Past that the four pulse counters drift to the corners of the screen
   and the trending row turns into a thin band. A cap that only engages once the
   content column exceeds the cap keeps the full-bleed intent everywhere it was
   actually doing work.
   ========================================================================== */
@media (min-width: 1600px) {
  #view-stats #statsWrap {
    max-width: 1480px;
    margin-inline: auto;
  }
}

/* ======== wtf ======== */
/* =============================================================================
   glass/wtf.css — glass + desktop layout for the WTF? explainer tab.

   PURELY ADDITIVE. This sheet must load AFTER market.css and phonehero.css; it
   layers overrides on top of them and rewrites nothing in place.

   MOBILE IS UNTOUCHED. Every declaration in this file lives inside a
   (min-width: 900px) query, so below 900px the file contributes zero
   declarations and phone rendering is byte-for-byte what it was.

   WHAT GETS REAL GLASS, AND WHY
   The tab has exactly two single-instance surfaces: the section header
   (#wtfHead) and the mini-app slab (#gwPhone, built by phonehero.js and
   appended to #view-wtf). Neither repeats, so both can carry a real
   backdrop-filter without a scroll cost.

   WHAT STAYS FLAT
   The six .wtf-card explainers are a grid, and the five .ph-feat-ic chips
   repeat inside the slab. Both get the blur-free treatment from
   .gw-glass-tile in glass.css: a translucent fill plus a lit edge, same
   family look, no compositing layer per item. See the performance rule at the
   top of glass.css.

   The markup carries no .gw-glass* classes (a second agent owns this tab's
   JavaScript, and the cards are static HTML), so the shared material is
   applied here through the same tokens those classes use. Blur values,
   fills, edges and shadows all come from glass.css; colours all come from the
   site palette tokens, so both the WTF pastel and dark themes work.
   ========================================================================== */

@media (min-width: 900px) {

  /* ---- 1. A SPACING SCALE FOR THE WHOLE TAB ----------------------------
     The view mixed three different rhythms: a 20px header margin, a
     clamp(12px,1.4vw,20px) grid gap and the slab's own 56/64px margins.
     One scale, inherited by the slab because it is a child of #view-wtf. */
  #view-wtf {
    --wtf-max: 1180px;   /* readable measure cap for both blocks           */
    --wtf-gap: 18px;     /* gutter between explainer cards                 */
    --wtf-pad: 26px;     /* interior padding of a glass panel              */
    padding-top: 26px;
    padding-bottom: 64px;
  }

  /* Both top-level blocks share one column, so the header, the card grid
     and the slab all start and end on the same two edges. */
  #wtfWrap {
    max-width: var(--wtf-max, 1180px);
    margin-inline: auto;
  }

  /* ---- 2. THE HEADER — REAL GLASS -------------------------------------
     One instance, sits at the top of a scrolling view: exactly the kind of
     chrome the blur is for. */
  #wtfHead {
    position: relative;
    margin-bottom: 26px;
    padding: 22px var(--wtf-pad, 26px) 20px;
    border-radius: 18px;
    background: var(--glass-fill);
    border: 1px solid var(--glass-edge);
    box-shadow: var(--glass-shadow);
  }
  #wtfHead h2 { margin-bottom: 10px; }
  #wtfNote { max-width: 66ch; font-size: 13.5px; line-height: 1.55; }

  /* the top light-catch, same geometry as .gw-glass-sheen */
  #wtfHead::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
    pointer-events: none;
  }

  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #wtfHead {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #wtfHead { background: var(--panel); }
  }

  /* ---- 3. THE CARD GRID — EVEN COLUMNS, NO RAGGED ROW ------------------
     auto-fill with a 280px floor put six cards into a 4+2 or 5+1 split at
     common desktop widths, which reads as a mistake. Six divides cleanly by
     two and by three, so pin the count and let the cards take the width. */
  #wtfGrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--wtf-gap, 18px);
    align-items: stretch;
  }

  /* ---- 4. THE CARDS — FLAT TILE, NOT GLASS ----------------------------
     Six now, more later: this is a grid, so it takes the blur-free fill.
     The pink tint gradient is kept so the cards still read as the shop's
     cards and not as generic panels. */
  .wtf-card {
    height: 100%;
    padding: 20px var(--wtf-pad, 26px);
    background:
      linear-gradient(180deg, var(--tint-weak), transparent),
      color-mix(in srgb, var(--panel) 78%, transparent);
    border-color: var(--glass-edge);
  }
  .wtf-card:hover { box-shadow: var(--glass-shadow); }

  /* Questions run one or two lines. Reserving two lines lands every answer
     on the same baseline across a row instead of stepping up and down. */
  .wtf-q { min-height: 2.4em; }
  .wtf-a { font-size: 14px; }

  /* ---- 5. THE MINI-APP SLAB — REAL GLASS ------------------------------
     phonehero.js appends this once, and only after the WTF tab opens. One
     instance, so it earns the blur. It also inherits --wtf-max, which lines
     its edges up with the card grid above it. */
  #gwPhone {
    position: relative;
    max-width: var(--wtf-max, 1180px);
    margin: 34px auto 0;
    padding: 26px var(--wtf-pad, 26px) 30px;
    border-radius: 20px;
    background: var(--glass-fill);
    border: 1px solid var(--glass-edge);
    box-shadow: var(--glass-shadow);
  }
  #gwPhone::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
    pointer-events: none;
  }

  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #gwPhone {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #gwPhone { background: var(--panel); }
  }

  /* ---- 6. INSIDE THE SLAB — TIGHTER RHYTHM ----------------------------
     26px under the sub-line and 48px between the columns left the panel
     mostly empty at desktop widths. */
  #gwPhone .ph-sechead { font-size: 24px; margin-bottom: 8px; }
  #gwPhone .ph-secsub { margin-bottom: 18px; max-width: 66ch; }
  #gwPhone .ph-grid { gap: 40px; align-items: center; }
  #gwPhone .ph-title { font-size: 26px; margin-bottom: 16px; }
  #gwPhone .ph-feats { gap: 10px; margin-bottom: 20px; }

  /* Five of these per slab, so they take the flat tile fill too. */
  #gwPhone .ph-feat-ic {
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border-color: var(--glass-edge);
  }
  #gwPhone .ph-feat-tx { min-width: 0; }
}

/* ---- 7. OVERSIZED CONTROLS ---------------------------------------------
   Desktop only, for the reason polish.css gives: a touch target wants to stay
   at or above ~44px, so the mobile sizes are left exactly as they are. The
   rail appears at 1100px, which is also where these read as out of scale. */
@media (min-width: 1100px) {
  #gwPhone .ph-cta {
    padding: 10px 22px;
    font-size: 13.5px;
    gap: 7px;
  }
  #gwPhone .ph-feat-ic {
    flex: 0 0 30px;
    width: 30px;
    height: 30px;
    font-size: 15px;
    border-radius: 9px;
  }
  #gwPhone .ph-feat { font-size: 15px; }
}

/* ---- 8. THREE COLUMNS ONCE THERE IS ROOM -------------------------------
   Below this the third column squeezes an 18px question into ~250px and the
   cards grow taller than they are wide. 1360px is where three columns clear
   ~320px each with the 264px rail in place. */
@media (min-width: 1360px) {
  #wtfGrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---- 9. REDUCED TRANSPARENCY -------------------------------------------
   Same courtesy glass.css extends to its own surfaces: solid panels, no
   blur, for anyone who cannot read text over a busy backdrop. Scoped to the
   same min-width so the mobile guarantee still holds. */
@media (min-width: 900px) and (prefers-reduced-transparency: reduce) {
  #wtfHead,
  #gwPhone {
    background: var(--panel);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .wtf-card {
    background: linear-gradient(180deg, var(--tint-weak), transparent), var(--panel);
  }
  #gwPhone .ph-feat-ic { background: var(--raised); }
  #wtfHead::before,
  #gwPhone::before { display: none; }
}

/* ======== terminal ======== */
/* =============================================================================
   glass/terminal.css — glass + desktop layout for the Terminal tab
   (#view-terminal, built by gterm.js, base styling in gterm.css).

   PURELY ADDITIVE. gterm.css, gterm.js, gchart.js and index.html are untouched;
   every declaration here is an override that wins by load order, so this file
   must be linked AFTER gterm.css and after glass.css, whose tokens it uses.

   BELOW 900px THIS FILE CONTRIBUTES ZERO DECLARATIONS. Every rule lives inside
   @media (min-width: 900px). The terminal collapses to a single stacked column
   under 780px and that stack is fine as it is; blur is also at its most
   expensive on the phone GPUs that render it. Nothing here shrinks a touch
   target, because every rule that tightens a control is desktop-only.

   GLASS BUDGET (see the performance rule at the top of glass.css). Real
   backdrop-filter goes on chrome that renders exactly once:
     .gt-rail  .gt-center  .gt-right  .gt-dock   the four terminal panels
     .gt-lane-seg                                the Gifts / NFTs switcher
     .gt-nft-rail  .gt-nft-main                  the NFT lane's two panels
     .gt-overlay  .gt-dialog  .gt-toast          modal scrim, dialog, toast
   Everything that REPEATS gets the blur-free translucent tile fill instead, and
   is additionally pinned to backdrop-filter:none so a future edit cannot leak
   blur into a list. The order book paints a dozen .gt-brow rows and The Tape
   paints forty .gt-trow rows, both on a 20s poll; a per-row backdrop-filter
   would re-blur every one of them on every scroll frame.

   ONE SURFACE IS DELIBERATELY LEFT OPAQUE: .gt-chartwrap. gchart.js clears its
   canvas to transparent and only fills a background in the empty state, so the
   candles are legible only because the wrapper behind them is solid --well.
   Making it translucent would drop the chart onto the page background.

   THE SWEEP PANEL IS TESTNET on a live marketplace and takes a destination
   wallet address. §9 gives it a hazard stripe, a hazard-toned edge, an enlarged
   TESTNET badge and a dashed wallet field so the status cannot be missed. The
   badge itself is built by gterm.js and is never hidden here.

   Colours resolve from the shared palette tokens only (--panel --void --raised
   --hover --well --hairline(-2) --ink-* --p300..--p700 --on-accent --tint(-weak)
   --gain --loss --sweep --ring) plus the glass tokens, so the WTF (light) and
   dark themes both work. No hardcoded colour anywhere in this file.
   ========================================================================== */

@media (min-width: 900px) {

  /* ---- 1 · SPACING SCALE -------------------------------------------------
     One rhythm for the whole desk instead of the 6/8/10/11/12/14/16px mix the
     base sheet grew into. Declared on :root because gterm.js appends the
     overlay, the dialogs and the toast host to document.body, outside
     .gt-shell, so a shell-scoped token would not reach them. */
  :root {
    --gt-1: 4px;
    --gt-2: 8px;
    --gt-3: 12px;
    --gt-4: 16px;
    --gt-5: 22px;
    --gt-gutter: clamp(16px, 1.7vw, 30px);
    --gt-r: 14px;
    --gt-r-sm: 10px;
  }

  /* ---- 2 · THE PAGE FRAME ------------------------------------------------
     The lane switcher and the two roots each carried their own horizontal
     padding, so the switcher sat on a different left edge from the panels it
     switches. They now share one gutter and one axis. The root also loses its
     12px top padding: .gt-shell already gaps the switcher away from it, and the
     two together read as a gap-and-a-half of dead space. */
  .gt-shell {
    gap: var(--gt-3);
  }
  .gt-lanes {
    padding: 0 var(--gt-gutter);
    gap: var(--gt-3);
  }
  .gt-root {
    padding: 0 var(--gt-gutter) var(--gt-4);
    gap: var(--gt-3);
  }
  .gt-nft-root {
    padding: 0 var(--gt-gutter) var(--gt-4);
    gap: var(--gt-3);
  }

  /* ---- 3 · CHROME: THE PANELS ARE THE GLASS ------------------------------
     Each of these renders once and sits over the scrolling page, which is
     exactly the case backdrop-filter is worth paying for. */
  .gt-rail,
  .gt-center,
  .gt-right,
  .gt-nft-rail,
  .gt-nft-main {
    position: relative;
    background: var(--glass-fill);
    border-color: var(--glass-edge);
    border-radius: var(--gt-r);
    box-shadow: var(--glass-shadow);
  }
  .gt-dock {
    position: relative;
    background: var(--glass-fill-strong);
    border-color: var(--glass-edge);
    border-radius: var(--gt-r);
    box-shadow: var(--glass-shadow);
  }
  .gt-lane-seg {
    background: var(--glass-fill-strong);
    border-color: var(--glass-edge);
  }

  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .gt-rail,
    .gt-center,
    .gt-right,
    .gt-dock,
    .gt-lane-seg,
    .gt-nft-rail,
    .gt-nft-main {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  /* No backdrop-filter support: solid panels, never unreadable text. */
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .gt-rail,
    .gt-center,
    .gt-right,
    .gt-dock,
    .gt-lane-seg,
    .gt-nft-rail,
    .gt-nft-main {
      background: var(--panel);
    }
  }

  /* the top light-catch. gterm.js sets className on these panels only at build
     time, so a pseudo-element is the safe way to add the sheen without needing
     the .gw-glass-sheen class in the markup. Ends fade so the 1px line does not
     escape the rounded corners. .gt-nft-main is left out on purpose: it is the
     one panel that scrolls itself, so an absolutely positioned sheen would
     scroll up out of the frame. */
  .gt-rail::before,
  .gt-center::before,
  .gt-right::before,
  .gt-dock::before,
  .gt-nft-rail::before {
    content: "";
    position: absolute;
    inset: 0 1px auto 1px;
    height: 1px;
    border-radius: var(--gt-r) var(--gt-r) 0 0;
    background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
    pointer-events: none;
    z-index: 1;
  }

  /* ---- 4 · MODAL CHROME --------------------------------------------------
     The scrim was a hardcoded rgba that read as a blue-black film over the WTF
     light theme. --void is the page's own backdrop colour in both themes. */
  .gt-overlay {
    background: color-mix(in srgb, var(--void) 74%, transparent);
  }
  .gt-dialog {
    background: var(--glass-fill-strong);
    border-color: var(--glass-edge);
    box-shadow: var(--glass-shadow);
  }
  .gt-toast {
    background: var(--glass-fill-strong);
    border-color: var(--glass-edge);
    box-shadow: var(--glass-shadow);
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .gt-overlay {
      -webkit-backdrop-filter: blur(6px) saturate(120%);
      backdrop-filter: blur(6px) saturate(120%);
    }
    .gt-dialog,
    .gt-toast {
      -webkit-backdrop-filter: blur(22px) saturate(var(--glass-sat));
      backdrop-filter: blur(22px) saturate(var(--glass-sat));
    }
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .gt-dialog,
    .gt-toast { background: var(--panel); }
  }
  /* the warning gate still has to out-shout the confirm behind it: the base
     sheet's .gt-dialog-warn ring is restated on top of the glass shadow, which
     would otherwise win on load order alone. */
  .gt-dialog-warn {
    box-shadow: 0 0 0 1px var(--sweep) inset, var(--glass-shadow);
  }

  /* ---- 5 · REPEATING ELEMENTS ARE FLAT -----------------------------------
     Same family look as the panels, a translucent fill and a lit edge, at none
     of the cost. The backdrop-filter:none is a guard, not a reset: it makes the
     no-blur rule survive a future edit that widens a glass selector. */
  .gt-coll,
  .gt-brow,
  .gt-trow,
  .gt-nft-row,
  .gt-av,
  .gt-stat,
  .gt-bs,
  .gt-mm,
  .gt-snp-t,
  .gt-sweep-deal,
  .gt-nft-cl,
  .gt-nft-edgechip,
  .gt-normie-act {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  /* the tile fill itself, for the ones that are actual tiles rather than rows */
  .gt-stat,
  .gt-bs,
  .gt-mm,
  .gt-snp-t,
  .gt-nft-edgechip {
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border-color: var(--glass-edge);
  }
  .gt-sweep-deal,
  .gt-nft-cl {
    background: color-mix(in srgb, var(--panel) 70%, transparent);
  }
  /* .gt-normie-act sits inside the dialog, which is already the STRONG fill, so
     a panel-toned tile on top of it would vanish. It stays recessed instead. */
  .gt-normie-act,
  .gt-nft-conc,
  .gt-pop {
    background: color-mix(in srgb, var(--well) 62%, transparent);
    border-color: var(--glass-edge);
  }

  /* equal-height tiles: grid stretch already matches their boxes, but the
     spread tile carries an extra percentage line, so without centring the three
     book stats read as three different heights. */
  .gt-bs,
  .gt-stat {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .gt-bookhead,
  .gt-id-grid,
  .gt-nft-stats {
    align-items: stretch;
    gap: var(--gt-2);
  }

  /* ---- 6 · INPUTS AND SEGMENTED CONTROLS --------------------------------- */
  .gt-search,
  .gt-sniper-in,
  .gt-sweep-in {
    background: color-mix(in srgb, var(--well) 70%, transparent);
    border-color: var(--glass-edge);
  }
  .gt-seg {
    background: color-mix(in srgb, var(--panel) 58%, transparent);
    border-color: var(--glass-edge);
  }
  .gt-seg-b {
    padding: 6px 11px;
  }
  .gt-seg-b[aria-pressed="true"] {
    background: color-mix(in srgb, var(--p400) 15%, transparent);
    color: var(--ink-hi);
    box-shadow: inset 0 -2px 0 var(--p400);
  }
  .gt-nft-chains {
    background: color-mix(in srgb, var(--well) 62%, transparent);
    border-color: var(--glass-edge);
  }

  /* ---- 7 · LEFT RAIL — kill the dead band ---------------------------------
     .gt-collist was capped at 40vh while .gt-identity was pushed to the bottom
     by margin-top:auto, so on a tall monitor the rail showed a list, a hole,
     then the identity strip. flex-grow lets the list take that free space.

     The max-height stays, raised rather than removed. It is load-bearing: the
     rail sits in a minmax(0,1fr) row whose height is resolved from content, and
     /v1/market/collections-all returns up to 500 rows. Without a cap the list's
     max-content contribution is the full 500 rows and the whole terminal grows
     to about 17,000px tall. The cap is what keeps the row bounded. */
  .gt-rail {
    padding: var(--gt-3);
    gap: var(--gt-3);
  }
  .gt-collist {
    flex: 1 1 auto;
    max-height: 48vh;
    min-height: 160px;
    padding-right: 2px;
  }
  .gt-coll {
    padding: 7px 8px;
  }
  .gt-identity {
    padding-top: var(--gt-3);
    gap: var(--gt-3);
    border-top-color: var(--glass-edge);
  }

  /* ---- 8 · CENTRE — the chart is the main event, so give it the height ---- */
  .gt-center {
    padding: var(--gt-3) var(--gt-4) var(--gt-4);
    gap: var(--gt-3);
  }
  .gt-chead {
    gap: var(--gt-3);
  }
  .gt-chartwrap {
    /* background deliberately untouched: gchart.js paints on a transparent
       canvas and relies on this wrapper being opaque. */
    min-height: clamp(280px, 32vh, 420px);
    border-radius: var(--gt-r-sm);
    border-color: var(--glass-edge);
  }
  .gt-snipe-banner {
    padding: var(--gt-3) var(--gt-4);
    border-radius: var(--gt-r-sm);
  }
  .gt-sniper {
    padding: var(--gt-3) var(--gt-4) var(--gt-4);
    border-radius: var(--gt-r-sm);
  }
  .gt-sniper-rules {
    gap: var(--gt-3);
    margin-bottom: var(--gt-3);
  }
  /* a full-bleed primary bar under a three-column rule row is more button than
     the action needs; sized to its label it stops competing with the banner. */
  .gt-sniper-arm {
    width: auto;
    min-width: 168px;
    padding: 9px var(--gt-5);
  }
  .gt-sniper-res {
    gap: var(--gt-1);
  }

  /* ---- 9 · SWEEP — TESTNET, AND IT HAS A DESTINATION WALLET FIELD --------
     This panel posts a destination wallet to a testnet escrow that returns
     simulated fills, and it lives on a production marketplace next to real
     order flow. The hazard stripe, the hazard-toned edge and the enlarged badge
     are all one signal read at a glance, before anyone types an address.
     The TESTNET badge is gterm.js's own element and is only made louder here. */
  .gt-sweep {
    position: relative;
    padding: var(--gt-4) var(--gt-3) var(--gt-3);
    gap: var(--gt-2);
    border-radius: var(--gt-r-sm);
    border-color: color-mix(in srgb, var(--sweep) 72%, transparent);
    box-shadow:
      inset 3px 0 0 var(--sweep),
      0 0 0 1px color-mix(in srgb, var(--sweep) 20%, transparent);
    flex: 0 0 auto;
  }
  .gt-sweep::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 5px;
    border-radius: var(--gt-r-sm) var(--gt-r-sm) 0 0;
    background: repeating-linear-gradient(
      135deg,
      var(--sweep) 0 7px,
      transparent 7px 14px
    );
    pointer-events: none;
  }
  .gt-sweep-head {
    padding-bottom: var(--gt-2);
    border-bottom: 1px dashed color-mix(in srgb, var(--sweep) 52%, transparent);
  }
  .gt-sweep-badge {
    padding: 3px 9px;
    border-radius: 6px;
    border-color: var(--sweep);
    background: color-mix(in srgb, var(--sweep) 20%, transparent);
    font-size: 10px;
    letter-spacing: .14em;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--sweep) 12%, transparent);
  }
  .gt-sweep-inputs {
    gap: var(--gt-2);
  }
  /* the destination wallet is the field that decides where value lands, so it
     is the field that wears the testnet marking rather than the panel alone */
  .gt-sweep-wallet {
    padding-top: 2px;
  }
  .gt-sweep-wallet .gt-sweep-lab {
    color: var(--sweep);
    font-weight: 800;
  }
  .gt-sweep-wallet .gt-sweep-in {
    border-style: dashed;
    border-color: color-mix(in srgb, var(--sweep) 62%, transparent);
    background: color-mix(in srgb, var(--well) 78%, transparent);
  }
  .gt-sweep-wallet .gt-sweep-in:focus {
    border-style: solid;
    border-color: var(--sweep);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--sweep) 26%, transparent);
  }
  .gt-sweep-deals {
    gap: var(--gt-1);
  }

  /* ---- 10 · RIGHT — the order book, aligned into real columns -------------
     .gt-brow-sz had no width, so the size column ended wherever the digits ran
     out and the right edge of the ladder was ragged. Fixed widths plus tabular
     figures give the book the two hard column rules a book is read by. */
  .gt-right {
    padding: var(--gt-3);
    gap: var(--gt-2);
  }
  .gt-book,
  .gt-tape {
    flex: 1 1 auto;
    padding: var(--gt-1);
    background: color-mix(in srgb, var(--well) 52%, transparent);
    border: 1px solid var(--hairline);
    border-radius: var(--gt-r-sm);
  }
  .gt-brow {
    padding: 5px 9px;
  }
  .gt-brow-price {
    width: 68px;
    font-variant-numeric: tabular-nums;
  }
  .gt-brow-sz {
    min-width: 38px;
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
  /* the spread divider spans the pane, not the padded inset */
  .gt-book-mid {
    margin: var(--gt-1) calc(var(--gt-1) * -1);
    padding: 5px var(--gt-3);
    border-top-color: var(--glass-edge);
    border-bottom-color: var(--glass-edge);
  }
  .gt-tapehead {
    padding-top: var(--gt-2);
    border-top-color: var(--glass-edge);
  }
  .gt-trow {
    padding: 5px 7px;
  }

  /* ---- 11 · DOCK — one row, actions parked on the right ------------------
     flex-wrap left the Buy/Sell pair dropping under the ladder at odd widths.
     The ladder takes the slack, the actions stay put. */
  .gt-dock {
    flex-wrap: nowrap;
    gap: var(--gt-4);
    padding: var(--gt-3) var(--gt-4);
  }
  .gt-ladder {
    flex: 1 1 auto;
  }
  .gt-ladder-ic {
    border-color: var(--glass-edge);
    background: color-mix(in srgb, var(--well) 66%, transparent);
  }
  .gt-actions {
    margin-left: auto;
    gap: var(--gt-3);
  }
  /* tightened horizontally only: the 11px vertical padding stays, so the
     control keeps its height and never becomes a small target. */
  .gt-tradebtn {
    min-width: 116px;
    padding: 11px var(--gt-4);
    border-radius: var(--gt-r-sm);
  }

  /* ---- 12 · NFT LANE — same rhythm, same tiles --------------------------- */
  .gt-nft-rail {
    padding: var(--gt-3);
    gap: var(--gt-3);
  }
  /* same reasoning as .gt-collist: the cap is raised, never removed, because it
     is what bounds a hundred-row list inside an auto-resolved grid row. */
  .gt-nft-list {
    flex: 1 1 auto;
    max-height: 66vh;
    min-height: 220px;
    padding-right: 2px;
  }
  .gt-nft-row {
    padding: 7px 8px;
  }
  .gt-nft-main {
    padding: var(--gt-4) var(--gt-5) var(--gt-5);
    gap: var(--gt-4);
  }
  .gt-nft-map {
    border-radius: var(--gt-r-sm);
    padding: var(--gt-3) var(--gt-4);
  }
  .gt-nft-conc {
    border-radius: var(--gt-r-sm);
    padding: var(--gt-3) var(--gt-4);
  }
  .gt-nft-mm,
  .gt-nft-edges {
    gap: var(--gt-2);
  }
  .gt-nft-clusters {
    padding-top: var(--gt-3);
    border-top-color: var(--glass-edge);
  }
  .gt-nft-pricenote {
    padding-top: var(--gt-3);
    border-top-color: var(--glass-edge);
  }

  /* ---- 13 · NORMIE POPUP ------------------------------------------------- */
  .gt-normie-grid {
    gap: var(--gt-3);
  }
  .gt-normie-act {
    padding: var(--gt-3) var(--gt-4);
    border-radius: var(--gt-r-sm);
  }
}

/* ---- 14 · WIDE DESKS ----------------------------------------------------
   The rail and the book column were fixed at 244px / 304px whatever the
   monitor, so past about 1500px every extra pixel went to the chart while the
   book stayed narrow enough to truncate most item names. */
@media (min-width: 1500px) {
  .gt-root {
    grid-template-columns: 272px minmax(0, 1fr) 348px;
  }
  .gt-nft-root {
    grid-template-columns: 292px minmax(0, 1fr);
  }
  .gt-brow-price { width: 78px; }
  .gt-brow-sz { min-width: 46px; }
}

/* Past this width the desk stops being a desk and becomes a smear, so it is
   capped and centred in the content column (the sidenav already offsets body). */
@media (min-width: 1800px) {
  .gt-lanes,
  .gt-root,
  .gt-nft-root {
    max-width: 1760px;
    margin-left: auto;
    margin-right: auto;
  }
}

/* ---- 15 · REDUCED TRANSPARENCY -----------------------------------------
   Some people cannot read text over a moving backdrop. Give them solid
   surfaces; every other rule above still applies. */
@media (min-width: 900px) and (prefers-reduced-transparency: reduce) {
  .gt-rail,
  .gt-center,
  .gt-right,
  .gt-dock,
  .gt-lane-seg,
  .gt-nft-rail,
  .gt-nft-main,
  .gt-dialog,
  .gt-toast {
    background: var(--panel) !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  .gt-overlay {
    background: var(--void) !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  .gt-stat,
  .gt-bs,
  .gt-mm,
  .gt-snp-t,
  .gt-sweep-deal,
  .gt-nft-cl,
  .gt-nft-edgechip,
  .gt-normie-act {
    background: var(--well) !important;
  }
  .gt-book,
  .gt-tape {
    background: var(--well) !important;
  }
}

/* ======== auctions ======== */
/* =============================================================================
   glass/auctions.css — glass + desktop layout for the AUCTIONS surfaces.

   Covers two things that both say "auction" to a visitor:
     1. #view-auctions, the Auction House tab (auction.js / auction.css, .au-*)
     2. the LIVE AUCTIONS window and BUY IT NOW rack that market-auctions.js
        self-mounts at the top of #view-gifts (.ma-*)

   PURELY ADDITIVE. Nothing in auction.css or market-auctions.css is rewritten;
   every declaration here is a later-loading override. Load this file AFTER
   auction.css, market-auctions.css and polish.css so it wins without
   !important (the two exceptions are the reduced-transparency and
   reduced-motion blocks at the bottom, which must beat everything by design).

   MOBILE IS UNTOUCHED. Every rule in this file lives inside
   @media (min-width: 900px). Below 900px this file contributes zero
   declarations, so phone and small-tablet rendering is exactly what it was.

   THE PERFORMANCE RULE. backdrop-filter forces its own compositing layer and
   re-blurs on every scroll frame, so real glass goes on CHROME ONLY: the tab
   masthead, the filter rail, the modal, the auction window frame and its two
   arrows. Anything that repeats — the board cards, the rack cards, the status
   pills — gets the blur-free .gw-glass-tile recipe (translucent fill, lit
   edge) instead. The board can hold a whole page of cards and the rack holds
   up to 60; blurring those would cost far more than the effect is worth.
   This file also switches OFF the existing per-card backdrop-filter on
   .au-pill for the same reason: that blur shipped once per card.

   COLOURS come from the shared palette and the glass tokens only. Every glass
   token is read with a palette fallback (var(--glass-fill, var(--panel))) so
   that if glass.css ever fails to load, these surfaces degrade to solid panels
   rather than to transparent, unreadable ones.
   ========================================================================== */

@media (min-width: 900px) {

  /* One spacing scale for the whole tab, so the masthead, the rail, the grid
     and the modal all step in the same units instead of eight ad-hoc numbers. */
  :root {
    --au-s1: 8px;
    --au-s2: 14px;
    --au-s3: 20px;
    --au-s4: 28px;
    --au-s5: 40px;
  }

  /* =========================================================================
     1 · PAGE SHELL
     ====================================================================== */
  .au-wrap {
    max-width: 1240px;
    padding: var(--au-s4) clamp(20px, 3vw, 40px) 72px;
  }

  /* =========================================================================
     2 · MASTHEAD — real glass. One instance, sits above the board, never
     repeats, so it is a legitimate blur surface.
     ====================================================================== */
  .au-head {
    position: relative;
    align-items: center;
    gap: var(--au-s4);
    margin-bottom: 0;
    padding: var(--au-s3) var(--au-s4);
    border-radius: 18px;
    overflow: hidden;
    background: var(--glass-fill, var(--panel));
    border: 1px solid var(--glass-edge, var(--hairline-2));
    box-shadow: var(--glass-shadow, 0 10px 28px -18px var(--shadow-card));
  }
  .au-head::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen, transparent) 22%, var(--glass-sheen, transparent) 78%, transparent);
    pointer-events: none;
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .au-head {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  .au-title { letter-spacing: -.015em; }
  .au-sub { margin-top: 6px; line-height: 1.55; }

  /* the CTA was carrying a hardcoded blue glow that no longer matches the
     palette; the lift now comes from the themed card shadow. */
  .au-new {
    padding: 10px 18px;
    font-size: 13.5px;
    border-radius: 12px;
    box-shadow: 0 6px 18px -6px var(--shadow-card);
  }

  /* =========================================================================
     3 · FILTER RAIL — chrome, so it earns glass. The chips inside go flat and
     let the rail carry the material; only the pressed chip fills.
     ====================================================================== */
  .au-filters {
    display: flex;
    width: -moz-fit-content;
    width: fit-content;
    gap: 4px;
    margin: var(--au-s3) 0 var(--au-s4);
    padding: 5px;
    border-radius: 999px;
    background: var(--glass-fill, var(--panel));
    border: 1px solid var(--glass-edge, var(--hairline-2));
    box-shadow: var(--glass-shadow, 0 10px 28px -18px var(--shadow-card));
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .au-filters {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  .au-filters .au-chip {
    background: transparent;
    border-color: transparent;
    padding: 9px 17px;
    line-height: 1.15;
    transition: background .15s ease, color .15s ease;
  }
  .au-filters .au-chip:hover { background: var(--hover); }
  .au-filters .au-chip[aria-pressed="true"] {
    background: var(--p400);
    color: var(--on-accent);
    box-shadow: 0 4px 12px -5px var(--shadow-card);
  }
  .au-filters .au-chip[aria-pressed="true"]:hover { color: var(--on-accent); }

  /* =========================================================================
     4 · THE BOARD — blur-free tiles, equal heights, aligned countdown row.
     Grid items already stretch to the tallest card in their row; pushing the
     body to fill and pinning the clock to the bottom means every countdown in
     a row lands on the same line instead of floating at a different height
     per card.
     ====================================================================== */
  .au-grid {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 18px;
  }
  .au-card {
    border-radius: 18px;
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border: 1px solid var(--glass-edge, var(--hairline-2));
    transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
  }
  .au-card:hover { box-shadow: var(--glass-shadow, 0 10px 28px -18px var(--shadow-card)); }
  .au-body {
    flex: 1 1 auto;
    padding: var(--au-s2) 15px 15px;
    gap: 7px;
  }
  .au-clock {
    margin-top: auto;
    padding-top: var(--au-s1);
  }
  /* the value column reads as data, so keep it on the numeric face */
  .au-v { font-variant-numeric: tabular-nums lining-nums; }

  /* status pills repeat once per card, so the blur they were carrying was the
     most expensive thing on the board. The tinted fill and inset ring already
     do the whole job. */
  .au-card .au-pill {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  /* =========================================================================
     5 · THE EMPTY STATE — the board is usually empty, so this panel is what
     most visitors actually see. It was rendering inside a single 238px grid
     column, which left it stranded against the left edge of a wide screen.
     Now it spans the grid, sits centred at a readable measure, and gets the
     full glass treatment: a lit top edge, a soft accent spotlight, and an
     empty dashed lot square above the headline that says "nothing is on the
     block" without a word of new copy.
     ====================================================================== */
  .au-grid > .au-empty {
    position: relative;
    grid-column: 1 / -1;
    justify-self: center;
    width: 100%;
    max-width: 620px;
    margin: var(--au-s3) 0 var(--au-s1);
    padding: 56px var(--au-s5);
    border-radius: 22px;
    overflow: hidden;
    background:
      radial-gradient(120% 100% at 50% -20%, var(--tint-weak) 0%, transparent 60%),
      var(--glass-fill, var(--panel));
    border: 1px solid var(--glass-edge, var(--hairline-2));
    box-shadow: var(--glass-shadow, 0 10px 28px -18px var(--shadow-card));
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .au-grid > .au-empty {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  .au-grid > .au-empty::after {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen, transparent) 22%, var(--glass-sheen, transparent) 78%, transparent);
    pointer-events: none;
  }
  /* the ornament belongs to the real empty state only. The loading state is a
     bare string in the same box and should stay plain, so it is keyed to the
     headline the empty state renders. */
  .au-grid > .au-empty:has(h3)::before {
    content: "";
    display: block;
    width: 72px;
    height: 72px;
    margin: 0 auto var(--au-s3);
    border-radius: 16px;
    border: 1px dashed var(--hairline-2);
    background: radial-gradient(circle at 50% 45%, var(--tint-weak) 0%, transparent 70%);
  }
  .au-empty h3 {
    font-size: 21px;
    letter-spacing: -.01em;
    margin: 0 0 10px;
  }
  .au-empty p {
    font-size: 14px;
    line-height: 1.6;
    max-width: 46ch;
  }

  /* =========================================================================
     6 · MODAL — chrome, and the one surface a bidder reads carefully.
     ====================================================================== */
  .au-back { padding: 6vh var(--au-s2) 56px; }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .au-back {
      -webkit-backdrop-filter: blur(10px) saturate(var(--glass-sat));
      backdrop-filter: blur(10px) saturate(var(--glass-sat));
    }
  }
  .au-modal {
    position: relative;
    max-width: 560px;
    border-radius: 20px;
    overflow: hidden;
    background: var(--glass-fill-strong, var(--panel));
    border: 1px solid var(--glass-edge, var(--hairline-2));
  }
  .au-modal::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen, transparent) 22%, var(--glass-sheen, transparent) 78%, transparent);
    pointer-events: none;
    z-index: 1;
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .au-modal {
      -webkit-backdrop-filter: blur(22px) saturate(var(--glass-sat));
      backdrop-filter: blur(22px) saturate(var(--glass-sat));
    }
  }
  .au-modal-hd { padding: 18px var(--au-s3); }
  .au-form {
    padding: 18px var(--au-s3) 22px;
    gap: var(--au-s2);
  }
  .au-two { gap: var(--au-s2); }

  /* inputs take the shared glass-input recipe: a translucent well, the glass
     edge, and an accent ring on focus. */
  .au-input {
    background: color-mix(in srgb, var(--well) 70%, transparent);
    border: 1px solid var(--glass-edge, var(--hairline-2));
    border-radius: 11px;
    padding: 11px 13px;
  }
  .au-input:focus {
    outline: none;
    border-color: var(--p300);
    box-shadow: 0 0 0 3px var(--tint-weak);
  }
  .au-field .hint { line-height: 1.5; }

  .au-seg { border-radius: 11px; }
  .au-seg-btn { padding: 10px; font-size: 13px; }

  .au-btn {
    padding: 11px 14px;
    font-size: 13.5px;
    border-radius: 12px;
  }
  /* the secondary action reads as glass rather than as a second solid slab, so
     the primary path stays obvious. */
  .au-btn.ghost {
    background: color-mix(in srgb, var(--panel) 55%, transparent);
    border: 1px solid var(--glass-edge, var(--hairline-2));
    transition: background .15s ease, border-color .15s ease;
  }
  .au-btn.ghost:hover {
    background: color-mix(in srgb, var(--hover) 75%, transparent);
    border-color: var(--p300);
  }

  /* detail: the art and the key/value stack share one baseline grid */
  .au-detail-top {
    padding: 18px var(--au-s3);
    gap: 16px;
    align-items: flex-start;
  }
  .au-detail-meta { flex: 1 1 auto; gap: 7px; }
  .au-bids {
    margin: 0 var(--au-s3);
    max-height: 220px;
  }

  /* =========================================================================
     7 · LIVE AUCTIONS WINDOW (.ma-*, top of #view-gifts)
     The viewport frame is one node no matter how many slides sit in the track,
     so the blur lives there and the slide card goes translucent on top of it.
     That is one compositing layer for the whole carousel instead of one per
     slide.
     ====================================================================== */
  .ma-viewport {
    border-radius: 20px;
    background: var(--glass-fill, var(--panel));
    border: 1px solid var(--glass-edge, var(--hairline-2));
    box-shadow: var(--glass-shadow, 0 10px 28px -18px var(--shadow-card));
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .ma-viewport {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  /* translucent, NOT blurred: it repeats once per slide. */
  .ma-card {
    align-items: center;
    gap: var(--au-s4);
    padding: var(--au-s3) var(--au-s4);
    background:
      radial-gradient(120% 90% at 12% -10%, var(--tint-weak) 0%, transparent 55%),
      color-mix(in srgb, var(--raised) 58%, transparent);
  }
  .ma-card-art { border-color: var(--glass-edge, var(--hairline)); }
  .ma-card-info { gap: 9px; }

  /* the two arrows are overlay chrome, so they get the real material */
  .ma-arrow {
    background: var(--glass-fill-strong, var(--raised));
    border: 1px solid var(--glass-edge, var(--hairline-2));
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .ma-arrow {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  .ma-prev { left: 14px; }
  .ma-next { right: 14px; }
  .ma-foot { margin-top: var(--au-s2); }

  /* =========================================================================
     8 · BUY IT NOW RACK — up to 60 cards in a row, so tiles only.
     ====================================================================== */
  .ma-rcard {
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border: 1px solid var(--glass-edge, var(--hairline-2));
  }
  .ma-rcard-body { padding: 11px 12px 13px; gap: 6px; }

  /* =========================================================================
     9 · THE .ma- EMPTY STATES — the band is empty most of the time too, so
     give it the same centred glass panel rather than a stretched dashed strip.
     ====================================================================== */
  .ma-empty {
    padding: var(--au-s4) var(--au-s3);
    border-radius: 16px;
    background: var(--glass-fill, var(--panel));
    border: 1px dashed var(--glass-edge, var(--hairline-2));
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .ma-empty {
      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
      backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    }
  }
  .ma-stage > .ma-empty {
    max-width: 620px;
    margin: 0 auto;
  }
}

/* =============================================================================
   REDUCED TRANSPARENCY — some people cannot read text sitting over a busy
   backdrop. Give them the solid panel underneath everything this file made
   translucent. !important because it has to beat the rules above.
   ========================================================================== */
@media (min-width: 900px) and (prefers-reduced-transparency: reduce) {
  .au-head,
  .au-filters,
  .au-grid > .au-empty,
  .au-modal,
  .au-card,
  .au-input,
  .au-btn.ghost,
  .ma-viewport,
  .ma-card,
  .ma-arrow,
  .ma-rcard,
  .ma-empty {
    background: var(--panel) !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  .au-back {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}

/* =============================================================================
   REDUCED MOTION — the only motion this file adds is on hover, and it is
   decoration, never data. Strip it. !important for the same reason.
   ========================================================================== */
@media (min-width: 900px) and (prefers-reduced-motion: reduce) {
  .au-card,
  .au-filters .au-chip,
  .au-btn.ghost {
    transition: none !important;
  }
}

/* ======== account ======== */
/* =============================================================================
   glass/account.css — the Account + rewards tab: glass pass and desktop layout.

   PURELY ADDITIVE. Loads after market.css, streak.css, arcade.css, badges.css,
   bagcheck.css, bingo.css, seasons.css, glass.css and polish.css, so every rule
   here is a plain later-wins override. Nothing upstream is edited in place.

   SCOPE: every declaration in this file lives inside @media (min-width: 900px).
   Below 900px the file contributes zero declarations, so phone and small-tablet
   rendering is byte-for-byte what it was before. Touch targets are only tightened
   on desktop, where a 44px pill is out of scale with the content.

   WHERE THE BLUR GOES (glass.css performance rule, restated because this tab is
   the one place it is easy to get wrong):
     real backdrop-filter -> #accAuthCard, #accHoldingsFilters and the four
       static gamify modals. Chrome only, and never more than one on screen.
     flat translucent fill, NO blur -> everything that repeats: the holdings grid
       cards, the collection filter chips, the six shelf card shells, the 30
       calendar cells, the arcade HUD cells and leaderboard rows, and the Bag
       Check stat cells. A 30-cell calendar plus a wallet-sized gift grid is
       exactly the kind of surface that turns backdrop-filter into single-digit
       fps scrolling.
     .gwa-modal is deliberately blur-free: it runs an animating game, so a
       blurred backdrop would be re-composited every frame for no visual gain.
     The five modal scrims (.gwa-back and friends) already carry blur(14px) of
       their own, so the modal panels themselves only need fill, edge and shadow.

   COLOUR: every value resolves from the shared palette and glass tokens, so both
   the WTF (light) and dark themes work. The background declarations carry the
   glass.css definition as an inline var() fallback, so a stylesheet deploy that
   lags this one can never leave a panel fully transparent with text on it.
   ========================================================================== */

@media (min-width: 900px) {

  /* ---- 0 · one spacing scale for the whole tab ---------------------------- */
  #view-account {
    --acc-s1: 8px;    /* inside a control            */
    --acc-s2: 14px;   /* between related rows        */
    --acc-s3: 22px;   /* between blocks              */
    --acc-s4: 34px;   /* between sections            */
    padding-top: 30px;
    padding-bottom: 72px;
  }

  /* The account view was full-bleed, so on a wide monitor the auth card floated
     in the middle of a very empty page and the holdings grid ran edge to edge.
     One measured column keeps both honest. */
  #accWrap { max-width: 1180px; margin-inline: auto; }

  /* ======================================================================== */
  /* 1 · LOGGED OUT — the auth panel                                          */
  /* ======================================================================== */

  /* centre the card in the viewport instead of pinning it to the top of an
     otherwise empty page */
  #accAuth {
    align-items: center;
    min-height: min(68vh, 620px);
    padding-block: var(--acc-s3);
  }

  #accAuthCard {
    width: min(468px, 100%);
    gap: var(--acc-s2);
    padding: 30px 30px 24px;
    border-radius: 22px;
    background: var(--glass-fill-strong, color-mix(in srgb, var(--panel) 84%, transparent));
    border: 1px solid var(--glass-edge, var(--hairline-2));
    box-shadow: var(--glass-shadow, 0 24px 70px var(--shadow-card)), 0 0 0 1px var(--tint-weak) inset;
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #accAuthCard {
      -webkit-backdrop-filter: blur(var(--glass-blur, 16px)) saturate(var(--glass-sat, 165%));
      backdrop-filter: blur(var(--glass-blur, 16px)) saturate(var(--glass-sat, 165%));
    }
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #accAuthCard { background: var(--panel); }
  }
  /* the top light-catch. ::before is already the slow conic halo, and the
     "#accAuthCard > *" z-index rule only matches elements, so the sheen rides
     ::after with its own z-index. */
  #accAuthCard::after {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    z-index: 2;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
    pointer-events: none;
  }

  #accAuthCard .acc-head h2 { margin-bottom: var(--acc-s1); }
  #accAuthCard .acc-sub { max-width: 44ch; }

  /* mode toggle: a 38px segmented control reads as a switch, not a third CTA */
  #accModeToggle { padding: 3px; border-radius: 11px; }
  .acc-mode { padding: 8px 10px; border-radius: 8px; font-size: 12.5px; }

  #accAuthForm { gap: var(--acc-s2); }
  .acc-field input { padding: 10px 12px; border-radius: 9px; }

  /* ONE filled button on the panel. The alternate sign-in paths were four
     identically weighted full-width slabs, which left the card with no primary
     at all; they drop to the shared glass-button treatment so the hierarchy is
     visible before you read a word. */
  .acc-primary {
    padding: 11px 14px;
    font-size: 13.5px;
    border-radius: 9px;
  }
  #accAuthCard .acc-ghost {
    padding: 10px 14px;
    font-size: 13px;
    border-radius: 9px;
    background: color-mix(in srgb, var(--panel) 55%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
    color: var(--ink-mid);
  }
  #accAuthCard .acc-ghost:hover {
    background: color-mix(in srgb, var(--hover) 75%, transparent);
    border-color: var(--p300);
    color: var(--ink-hi);
  }

  /* The panel carried three separate "or" rules — one per alternate path — so a
     configured build showed the same divider three times. Keep the first one
     that is actually visible and drop the rest; the alternates then read as one
     group under a single separator. The [hidden] tests are the same flags
     market.js already toggles. */
  #accAuthCard #accTgWrap:not([hidden]) ~ #accGoogleWrap .acc-divider,
  #accAuthCard #accTgWrap:not([hidden]) ~ .acc-divider,
  #accAuthCard #accGoogleWrap:not([hidden]) ~ .acc-divider { display: none; }

  #accAuthCard .acc-divider { margin-block: 2px; }
  #accTgMount { min-height: 0; }
  #accAuthCard .acc-fine { max-width: 42ch; margin-inline: auto; }

  /* ======================================================================== */
  /* 2 · LOGGED IN — profile head, wallet row, Bag Check panel                 */
  /* ======================================================================== */

  /* These three sit in the normal scroll flow with nothing ever passing behind
     them, so they take the glass fill and edge but no backdrop-filter: the blur
     would sample a static background and cost a compositing layer for it. */
  #accProfileHead,
  #accWalletRow,
  #gwBagCheckAccount.gwbag-account {
    position: relative;
    padding: 18px 22px;
    border: 1px solid var(--glass-edge, var(--hairline-2));
    border-radius: 18px;
    background: var(--glass-fill, color-mix(in srgb, var(--panel) 62%, transparent));
    box-shadow: var(--glass-shadow, 0 10px 34px -14px var(--shadow-card));
  }
  #accProfileHead::before,
  #accWalletRow::before,
  #gwBagCheckAccount.gwbag-account::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
    pointer-events: none;
  }

  #accProfileHead { gap: var(--acc-s3); margin-bottom: var(--acc-s2); }
  #accWalletRow { gap: var(--acc-s3); margin-bottom: var(--acc-s2); }
  #gwBagCheckAccount.gwbag-account { margin: var(--acc-s2) 0 var(--acc-s4); }

  #accAvatar { width: 52px; height: 52px; font-size: 23px; }
  #accName { font-size: clamp(24px, 2.6vw, 34px); }
  #accLogout { padding: 8px 15px; border-radius: 9px; }

  .acc-wchip-addr { padding: 6px 12px; border-radius: 9px; }

  /* the three Bag Check stat cells repeat, so they get the tile fill */
  .gwbag-accountstats { gap: var(--acc-s1); }
  #gwBagCheckAccount .gwbag-stat {
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border: 1px solid var(--glass-edge, var(--hairline));
    border-radius: 12px;
  }

  /* ======================================================================== */
  /* 3 · HOLDINGS — the wallet's gifts                                         */
  /* ======================================================================== */

  #accHoldingsHead { margin-bottom: var(--acc-s2); }
  #accHoldingsHead h3 { font-size: clamp(20px, 2.2vw, 28px); }

  /* the collection filter rail is chrome, not content: one element, named in
     glass.css as a glass surface, and it never repeats. It was a bare row of
     chips with nothing holding them, so it also gains a body. */
  #accHoldingsFilters {
    gap: var(--acc-s1);
    padding: 10px 12px;
    margin-bottom: var(--acc-s3);
    border: 1px solid var(--glass-edge, var(--hairline-2));
    border-radius: 14px;
    background: var(--glass-fill, color-mix(in srgb, var(--panel) 62%, transparent));
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #accHoldingsFilters {
      -webkit-backdrop-filter: blur(var(--glass-blur, 16px)) saturate(var(--glass-sat, 165%));
      backdrop-filter: blur(var(--glass-blur, 16px)) saturate(var(--glass-sat, 165%));
    }
  }
  /* market.js empties the rail when there is nothing to filter — an empty glass
     box is worse than no box */
  #accHoldingsFilters:empty { display: none; }

  /* chips repeat: flat fill, no blur */
  .acc-hchip {
    padding: 6px 11px;
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
  }
  .acc-hchip:hover { border-color: color-mix(in srgb, var(--p300) 55%, transparent); }
  .acc-hchip-c { background: color-mix(in srgb, var(--well) 70%, transparent); }

  /* grid cards repeat by the hundred: tile treatment, never backdrop-filter */
  #accHoldingsGrid.view-grid {
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 16px;
  }
  #accHoldingsGrid .card {
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    border-color: var(--glass-edge, var(--hairline-2));
    border-radius: 14px;
  }
  #accHoldingsGrid .card:hover { border-color: color-mix(in srgb, var(--p300) 55%, transparent); }
  /* equal-height tiles: the art is square, so let the body take the slack and
     pin the collection line to the bottom edge. Cards with and without a
     collection name then line up instead of stepping. */
  #accHoldingsGrid .card .c-body { flex: 1 1 auto; padding: 11px 12px 13px; }
  #accHoldingsGrid .card .acc-hcoll { margin-top: auto; }

  #accHoldingsState {
    padding: 46px 20px;
    border: 1px dashed var(--glass-edge, var(--hairline-2));
    border-radius: 16px;
    background: color-mix(in srgb, var(--panel) 62%, transparent);
  }

  /* ======================================================================== */
  /* 4 · YOUR STUFF — the six relocated reward cards                           */
  /* ======================================================================== */

  /* The cards were built to sit full-bleed on the landing page, each with its
     own clamp(14px, 4vw, 54px) side margin. Inside a padded view that margin
     stacks on top of the view padding, so the shelf sat in a double inset with
     six different vertical gaps. One column, one gap, no inset. */
  #gwShelf {
    display: flex;
    flex-direction: column;
    gap: var(--acc-s3);
    max-width: 1180px;
    margin: 44px auto 0;
  }
  #gwShelf > h3 { margin: 0; font-size: clamp(20px, 2.2vw, 28px); }
  #gwShelf > .gwstk-card,
  #gwShelf > .gba-card,
  #gwShelf > .gwa-card,
  #gwShelf > .gwbag-card,
  #gwShelf > .gwb-card,
  #gwShelf > .gws-card { margin: 0; }

  /* One surface for all six. Flat translucent fill, no blur: six stacked
     backdrop-filter panels would each re-blur on every scroll frame. */
  #gwShelf .gwstk-shell,
  #gwShelf .gwa-shell,
  #gwShelf .gwbag-shell,
  #gwShelf .gwb-shell,
  #gwShelf .gws-shell,
  #gwShelf > .gba-card {
    padding: 26px;
    border: 1px solid var(--glass-edge, var(--hairline));
    border-radius: 20px;
    background: color-mix(in srgb, var(--panel) 78%, transparent);
    box-shadow: var(--glass-shadow, 0 18px 48px var(--shadow-card));
  }
  /* the badges card carries its padding on the inner shell */
  #gwShelf > .gba-card { padding: 0; }
  #gwShelf .gba-shell { padding: 26px; }

  /* headline scale: the badges card topped out at 54px against 40px everywhere
     else, which made the shelf read as six unrelated pages */
  #gwShelf .gba-title { font-size: clamp(25px, 2.8vw, 40px); }

  /* aligned columns: three of the cards use a fixed art column at three
     different widths, and their art blocks were 150 / 145 / auto tall */
  #gwShelf .gwa-shell,
  #gwShelf .gwbag-shell,
  #gwShelf .gwb-shell { grid-template-columns: 200px minmax(0, 1fr); gap: var(--acc-s3); }
  #gwShelf .gwa-cardart,
  #gwShelf .gwbag-mark { height: 150px; }
  #gwShelf .gwb-mark { min-height: 150px; }

  /* one CTA size across the shelf */
  #gwShelf .gwstk-claim { min-height: 40px; font-size: 13.5px; line-height: 40px; padding: 0 26px; }
  #gwShelf .gwa-open,
  #gwShelf .gwa-start,
  #gwShelf .gwbag-open,
  #gwShelf .gwbag-flexbtn,
  #gwShelf .gwb-open,
  #gwShelf .gwb-account,
  #gwShelf .gws-open,
  #gwShelf .gba-open,
  #gwShelf .gba-action { min-height: 40px; padding: 0 20px; font-size: 13.5px; }

  /* ---- 4a · the daily check-in calendar ---------------------------------- */

  /* 30 square cells across a 1180px card grew to ~96px each, so the calendar
     was taller than the card that holds it. Cap the grid and centre it.
     Gated at 941px because streak.css still runs the 6-column layout up to
     940px, and a capped 6-column grid would make the cells taller, not
     shorter. */
  @media (min-width: 941px) {
    #gwShelf .gwstk-cal { max-width: 820px; margin-inline: auto; gap: 10px; }
  }

  /* 30 repeating cells: flat fill, no blur. The marked, milestone and
     today cells are excluded so they keep the fills, borders and glows
     streak.css gives them — an id-scoped rule would otherwise outrank them. */
  #gwShelf .gwstk-day:not(.is-x):not(.is-m7):not(.is-m30) {
    background: color-mix(in srgb, var(--panel) 62%, transparent);
    border-color: var(--glass-edge, var(--hairline));
  }

  /* Before the first check-in every cell is blank, so the grid read as thirty
     empty boxes rather than a ladder you have not started. Fading the plain
     days lets the three reward cells and today's outline carry the block. The
     :has() test is a progressive enhancement — where it is unsupported the
     calendar simply renders as it does today. */
  #gwShelf .gwstk-cal:not(:has(.gwstk-day.is-x)) .gwstk-day:not(.is-m3):not(.is-m7):not(.is-m30):not(.is-today) {
    opacity: .48;
  }

  #gwShelf .gwstk-head { margin-bottom: var(--acc-s3); }
  #gwShelf .gwstk-foot { margin-top: var(--acc-s2); }

  /* ---- 4b · the arcade card ---------------------------------------------- */

  /* the copy column was unbounded, so the headline and the paragraph wrapped on
     different measures inside the same card */
  #gwShelf .gwa-copy p,
  #gwShelf .gwbag-copy p,
  #gwShelf .gba-copy,
  #gwShelf .gws-copy { max-width: 62ch; }

  /* ======================================================================== */
  /* 5 · THE REWARD MODALS                                                     */
  /* ======================================================================== */

  /* Static-content modals: real glass. Their scrims already blur the page, so
     the panel gets the strong fill, the lit edge and the glass shadow, plus its
     own backdrop-filter for the part of the scrim that shows through. */
  .gwbag-modal,
  .gwb-modal,
  .gws-modal,
  .gba-modal {
    background: var(--glass-fill-strong, color-mix(in srgb, var(--panel) 84%, transparent));
    border: 1px solid var(--glass-edge, var(--hairline-2));
    box-shadow: var(--glass-shadow, 0 28px 100px var(--shadow-card));
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .gwbag-modal,
    .gwb-modal,
    .gws-modal,
    .gba-modal {
      -webkit-backdrop-filter: blur(22px) saturate(var(--glass-sat, 165%));
      backdrop-filter: blur(22px) saturate(var(--glass-sat, 165%));
    }
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .gwbag-modal,
    .gwb-modal,
    .gws-modal,
    .gba-modal { background: var(--panel); }
  }

  /* The arcade modal runs an animating game. Same material, no backdrop-filter:
     this is the one panel where re-blurring every frame would be felt. */
  .gwa-modal {
    background: var(--glass-fill-strong, color-mix(in srgb, var(--panel) 84%, transparent));
    border-color: var(--glass-edge, var(--hairline-2));
    box-shadow: var(--glass-shadow, 0 28px 100px var(--shadow-card));
  }
  /* the HUD cells and the leaderboard rows both repeat: flat fill only */
  .gwa-hud div,
  .gwa-boardrow {
    background: color-mix(in srgb, var(--panel) 70%, transparent);
    border-color: var(--glass-edge, var(--hairline));
  }
  /* .gwa-boardrow.is-viewer keeps its own lit fill from arcade.css — higher
     specificity, so the tile fill above never reaches it. */

  /* ======================================================================== */
  /* 6 · ACCESSIBILITY GUARDS                                                  */
  /* ======================================================================== */

  /* Anyone who has asked for less transparency gets solid surfaces here too,
     matching the guard glass.css already ships. */
  @media (prefers-reduced-transparency: reduce) {
    #accAuthCard,
    #accHoldingsFilters,
    #accProfileHead,
    #accWalletRow,
    #gwBagCheckAccount.gwbag-account,
    #accHoldingsState,
    #accHoldingsGrid .card,
    .acc-hchip,
    #gwShelf .gwstk-shell,
    #gwShelf .gwa-shell,
    #gwShelf .gwbag-shell,
    #gwShelf .gwb-shell,
    #gwShelf .gws-shell,
    #gwShelf > .gba-card,
    #gwShelf .gwstk-day:not(.is-x):not(.is-m7):not(.is-m30),
    .gwa-modal,
    .gwbag-modal,
    .gwb-modal,
    .gws-modal,
    .gba-modal {
      background: var(--panel) !important;
      -webkit-backdrop-filter: none !important;
      backdrop-filter: none !important;
    }
    #accAuthCard::after,
    #accProfileHead::before,
    #accWalletRow::before { display: none; }
  }

  /* the faded-ladder treatment is a contrast reduction, so restore full
     contrast when more contrast is asked for */
  @media (prefers-contrast: more) {
    #gwShelf .gwstk-cal:not(:has(.gwstk-day.is-x)) .gwstk-day { opacity: 1; }
  }
}
