:root {
  /* blue, white, black — the dark surfaces are black, not navy */
  --ink:#0b0b0e; --ink-soft:#2b2b33; --slate:#5c5f6b; --slate-light:#8a8d99;
  --blue:#1f52ff; --blue-deep:#0b39d6; --blue-wash:#eef2ff; --blue-tint:#f5f7fc;
  --white:#ffffff; --line:#e6e7ec; --line-soft:#f0f1f5;
  --amber:#f5a524; --green:#10b981; --green-wash:#e7f8f1; --black:#000000;
  --mono:"SF Mono","JetBrains Mono",ui-monospace,"Cascadia Code",Menlo,monospace;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,Roboto,sans-serif;
  --shadow:0 1px 2px rgba(10,17,48,.04), 0 8px 24px rgba(10,17,48,.06);
  --shadow-lg:0 12px 40px rgba(10,17,48,.12);
}
*{box-sizing:border-box}
/* The whole app shows and hides things with the `hidden` attribute (auth state,
   tab panels, loading skeletons, empty states). Any author rule that sets
   `display` on those elements would otherwise beat the browser's own
   [hidden]{display:none}, leaving them stuck on screen. */
[hidden]{display:none !important}
/* The canvas behind the page. Once html carries a background, body's no longer
   propagates to it, so overscrolling past the footer (or above the header)
   shows this instead of white. Both ends of the storefront are black, so the
   bounce matches rather than flashing a white strip under the footer. */
html{background:var(--black)}
html.html-dash{background:var(--blue-tint)}
body{margin:0;background:var(--white);color:var(--ink);font-family:var(--sans);-webkit-font-smoothing:antialiased;line-height:1.5}

/* The storefront shell.
   The page colour sits on .site-main rather than on <body>, so the white ends
   exactly where the footer starts. With it on <body> the white kept painting
   behind and below the footer, which is what showed through in the safe area
   at the bottom of a phone: the footer looked like a black block laid on top
   of a white page rather than the end of it.
   The column layout also pins the footer to the bottom on short pages. */
body.site{background:var(--black);min-height:100vh;min-height:100dvh;display:flex;flex-direction:column}
.site-main{background:var(--white);flex:1 0 auto;min-width:0}
body.site>footer{flex-shrink:0}
a{color:inherit;text-decoration:none}
h1,h2,h3{margin:0;letter-spacing:-.02em;text-wrap:balance}
/* viewport-fit=cover lets content reach the physical screen edges, so in
   landscape on a notched phone the side insets are respected here rather than
   letting text slide under the rounded corner. */
.wrap{max-width:1240px;margin:0 auto;padding:0 max(24px,env(safe-area-inset-left)) 0 max(24px,env(safe-area-inset-right))}
/* Chrome that spans a full-width dark bar (header, footer) uses a wider track,
   so a big monitor does not leave a wall of empty black either side of the
   menu. Page content keeps the 1240px measure, which stays comfortable to read. */
.wrap-wide{max-width:1760px}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* The height of the sticky header, measured, not guessed: 125px while the
   category row shows and 64px once it is hidden. Anything that sticks below the
   header or scrolls to an anchor must offset by this, or it ends up underneath
   the header instead of below it. */
:root{--nav-h:125px}
@media(max-width:1100px){:root{--nav-h:64px}}
/* Sticky column below the header, and the matching offset for #anchor jumps. */
.stick-below{position:sticky;top:calc(var(--nav-h) + 16px)}
.anchor-below{scroll-margin-top:calc(var(--nav-h) + 24px)}
.eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--blue);font-weight:600}

/* ── Announcement ── */
.announce{background:var(--black);color:#c9c9d0;font-size:12.5px;text-align:center;padding:9px 16px}
.announce b{color:#fff}
.announce a{color:#7f9dff;font-weight:600}

/* ── Header (dark) ── */
.nav{position:sticky;top:0;z-index:50;background:var(--black);color:#fff}
.nav-in{display:flex;align-items:center;gap:16px;height:70px}
/* Giving the logo and the actions an equal flex basis makes the search sit in
   the true centre of the bar. Auto margins alone only centre it in whatever
   space is left over, which is off-centre because the two sides differ in width. */
/* min-width:max-content is what keeps the logo readable: with a plain
   min-width:0 the equal-basis track collapsed the mark to nothing once the
   search bar wanted more room than the bar had. The two sides stay equal, and
   so the search stays centred, right up until the logo hits its natural width. */
/* Only where the inline search bar actually exists. Below that the bar becomes
   a three-part grid instead, and these equal-basis tracks would fight it. */
@media(min-width:1101px){
  .nav-in>.logo{flex:1 1 0;min-width:max-content}
  .nav-in>.nav-actions{flex:1 1 0;justify-content:flex-end;min-width:max-content}
}
.nav-left{display:none;align-items:center;gap:8px}
.logo{font-size:22px;font-weight:800;letter-spacing:-.03em;white-space:nowrap}
.logo .a{color:#fff} .logo .b{color:#4f7cff}
.search{flex:1;max-width:560px;display:flex;align-items:center;gap:10px;background:#fff;border:1px solid transparent;border-radius:30px;padding:0 6px 0 16px;height:48px;min-width:0}
.search:focus-within{box-shadow:0 0 0 3px rgba(31,82,255,.35)}
.search svg{color:var(--slate-light);flex-shrink:0}
.search input{border:0;outline:0;flex:1;font-size:14.5px;font-family:var(--sans);min-width:0;background:transparent;color:var(--ink)}
.search-go{width:40px;height:40px;flex-shrink:0;border:0;border-radius:50%;background:var(--blue);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer}
.search-go:hover{background:var(--blue-deep)}
.nav-actions{display:flex;align-items:center;gap:10px;margin-left:auto}
.icon-btn{position:relative;width:44px;height:44px;border-radius:50%;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;color:#fff;cursor:pointer;flex-shrink:0}
.icon-btn:hover{background:rgba(255,255,255,.13)}
.cart-badge{position:absolute;top:-4px;right:-4px;background:var(--blue);color:#fff;font-size:11px;font-weight:700;min-width:19px;height:19px;border-radius:10px;display:flex;align-items:center;justify-content:center;padding:0 5px;border:2px solid var(--black)}
.btn{display:inline-flex;align-items:center;gap:8px;font-weight:700;font-size:14px;border-radius:11px;padding:11px 18px;cursor:pointer;border:1px solid transparent;white-space:nowrap;transition:transform .08s ease}
.btn:active{transform:translateY(1px)}
.btn-primary{background:var(--blue);color:#fff}
.btn-primary:hover{background:var(--blue-deep)}
/* There was no disabled style on .btn at all, only on the auth and licence
   variants. A saving button therefore looked exactly like a ready one: still
   fully blue, still inviting a second click on a request already in flight. */
.btn:disabled,.btn[disabled]{opacity:.55;cursor:not-allowed;transform:none}
.btn:disabled:hover,.btn[disabled]:hover{background:var(--blue)}
.btn-ghost:disabled:hover,.btn-ghost[disabled]:hover{background:transparent}
.btn-ghost{background:#fff;border-color:var(--line);color:var(--ink)}
.btn-ghost:hover{border-color:#c9d2ea}
/* The confirm dialog asks for this on destructive actions and it was never
   defined, so "Revoke key" and "Delete" rendered as an unstyled button that
   looked no more serious than Cancel. */
.btn-danger{background:#c8352f;color:#fff;border-color:#c8352f}
.btn-danger:hover{background:#a92a25;border-color:#a92a25}
.btn-danger:disabled:hover,.btn-danger[disabled]:hover{background:#c8352f}
.btn-ink{background:var(--black);color:#fff}
.btn-ink:hover{background:#1a1a1a}
.btn-outline{background:transparent;border:1px solid rgba(255,255,255,.22);color:#fff}
.btn-outline:hover{background:rgba(255,255,255,.09);border-color:rgba(255,255,255,.4)}
.sign-in{font-weight:600;font-size:14px;color:#c9c9d0;padding:11px 6px;white-space:nowrap}
.sign-in:hover{color:#fff}
.nav-cats-row{background:var(--black);border-top:1px solid rgba(255,255,255,.08)}
.nav-cats-in{display:flex;align-items:center;height:46px;gap:6px}
/* The category row sits as one centred group. Centring is done with auto
   margins rather than justify-content: on a scrollable flex row, centred
   content that overflows gets clipped at the start with no way to scroll back
   to it, whereas auto margins simply collapse and the row scrolls normally. */
/* overflow is visible, not auto. Setting overflow on one axis makes the other
   compute to auto as well, which turns this row into a clipping box: the
   subcategory flyouts below open downward out of it and were cut off at the
   row's edge. It wraps instead of scrolling if it ever runs out of room, which
   loses nothing since below 1100px this row is replaced by the phone menu. */
.cat-links{display:flex;align-items:center;gap:1px;flex-wrap:nowrap;overflow:visible;flex:1;min-width:0}
.cat-links>:first-child{margin-left:auto}
.cat-links>:last-child{margin-right:auto}
/* The authoritative .cat-links a rules live further down, beside .cat-pill.
   A second set here was silently losing to them, which is why changing the
   size in this block had no effect on screen at all. */
.cat-links a.cat-free{color:#3ddc97}

/* ── Category flyouts ────────────────────────────────────────
   Opens on hover and on keyboard focus. The flyout is a sibling of the link
   inside .cat-item, so moving the pointer down into it keeps the whole item
   hovered and it stays open. */
.cat-item{position:relative}
/* Sized to its own content rather than a fixed 300px, so with every label on
   one line the panel is exactly as wide as it needs to be. */
.cat-flyout{position:absolute;top:100%;left:0;z-index:150;width:max-content;max-width:min(540px,90vw);
  background:#fff;border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg);
  padding:9px;opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .14s,transform .14s,visibility .14s}
.cat-item:hover .cat-flyout,.cat-item:focus-within .cat-flyout{opacity:1;visibility:visible;transform:none}
/* The link row is dark; the panel is not, so the colours are restated rather
   than inherited from .cat-links a. */
/* Black rather than the soft ink used elsewhere: this panel is small text on
   white and needs the contrast to read as a list of real destinations. */
.cat-flyout a{display:block;font-size:12.5px;font-weight:500;color:var(--black);
  padding:6px 9px;border-radius:7px;white-space:nowrap}
.cat-flyout a:hover{background:var(--blue-tint);color:var(--blue)}
.cat-flyout-all{font-weight:700 !important;color:var(--blue) !important;
  border-bottom:1px solid var(--line-soft);border-radius:7px 7px 0 0;margin-bottom:5px;padding-bottom:8px !important}
/* One column, one item per line. Two columns split the list left and right,
   so reading it meant jumping across the panel instead of straight down. */
.cat-flyout-grid{display:flex;flex-direction:column;gap:0}
/* The last few categories sit near the right edge, so their panels open
   leftward instead of off the screen. */
.cat-item:nth-last-child(-n+3) .cat-flyout{left:auto;right:0}

/* ── Phone: expandable category rows ─────────────────────── */
.m-cat{border-radius:11px}
.m-cat > summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:11px;
  padding:10px 12px;border-radius:9px;font-weight:500;font-size:14px;color:var(--ink)}
.m-cat > summary::-webkit-details-marker{display:none}
.m-cat > summary::after{content:"";margin-left:auto;flex-shrink:0;width:7px;height:7px;
  border-right:2px solid var(--slate-light);border-bottom:2px solid var(--slate-light);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .18s ease}
.m-cat[open] > summary::after{transform:rotate(-135deg) translate(-2px,-2px)}
.m-cat > summary:active{background:var(--blue-tint);color:var(--blue)}
.m-sub{display:flex;flex-direction:column;gap:0;padding:0 0 6px 43px}
.m-sub a{font-size:13px;font-weight:400;padding:7px 12px;color:var(--slate)}
@media(prefers-reduced-motion:reduce){.m-cat > summary::after{transition:none}}
.hamburger{display:flex;align-items:center;gap:9px;background:transparent;border:0;color:#fff;font-weight:600;font-size:14px;padding:8px 2px;cursor:pointer}
.nav-hide-sm{display:flex}
.nav-show-sm{display:none}
.nav-hide-cats{display:flex}
.nav-show-cats{display:none}
/* Tablets and phones share one header: menu and search on the left, the logo
   centred, cart and account on the right. Three grid tracks with the outer two
   equal is what actually centres the logo, since the two side groups differ in
   width and auto margins would only centre it in the leftover space. */
@media(max-width:1100px){
  .nav-hide-cats{display:none !important}
  .nav-show-cats{display:flex !important}
  .cat-links{display:none}

  .nav-in{display:grid;grid-template-columns:1fr auto 1fr;gap:10px}
  .nav-left{justify-self:start}
  .nav-in>.logo{justify-self:center;min-width:0;overflow:hidden;text-overflow:ellipsis}
  .nav-in>.nav-actions{justify-self:end;margin-left:0}
}
@media(max-width:720px){
  .nav-hide-sm{display:none !important}
  .nav-show-sm{display:flex !important}
  .nav-in{height:62px;gap:8px}
  .logo{font-size:19px}
  .nav-left,.nav-actions{gap:6px}
  .icon-btn{width:42px;height:42px}
}
/* Narrow phones: the wordmark alone would push the side groups off the edge. */
@media(max-width:400px){
  .icon-btn{width:38px;height:38px}
  .logo{font-size:17px}
}

/* ── Hero ── */
.hero{position:relative;overflow:hidden;background:linear-gradient(180deg,#f6f8fe 0%,#fff 72%)}
.hero-net{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;opacity:.55;z-index:0}
.hero-mascot{position:absolute;right:0;top:0;bottom:0;width:46%;max-width:600px;pointer-events:none;display:flex;align-items:center;justify-content:center;z-index:1}
.mascot-slot{width:74%;aspect-ratio:1;border:2px dashed #c9d6f5;border-radius:26px;background:radial-gradient(closest-side,var(--blue-wash),transparent);display:flex;align-items:center;justify-content:center;opacity:.75}
.mascot-slot span{font-family:var(--mono);font-size:12px;color:var(--blue-deep);letter-spacing:.05em}
/* 690px rather than 600: the hero paragraph needs the extra measure to sit on
   two lines. It still clears the mascot, which starts around 644px in from the
   left on a 1240px page and is decorative anyway. */
.hero-inner{position:relative;z-index:2;max-width:690px;padding:56px 0 62px}
.hero-badge{display:inline-flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--line);border-radius:30px;padding:8px 18px 8px 8px;box-shadow:var(--shadow);font-family:var(--mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;font-weight:600;color:var(--ink)}
.hero-badge .bic{width:28px;height:28px;border-radius:9px;background:var(--blue-wash);display:flex;align-items:center;justify-content:center;color:var(--blue)}
.hero h1{font-size:60px;font-weight:800;line-height:1.02;margin:22px 0 0}
/* The lead is a smaller line above, so "premium code." carries the weight and
   runs visibly longer than it. Sized in em, so it tracks the h1 through every
   breakpoint without a second set of rules. Block display fixes the line break
   rather than leaving it to wrapping. */
.hero h1 .hl-lead{display:block;font-size:.78em;font-weight:800;color:var(--ink);letter-spacing:-.02em;margin-bottom:.08em}
.hero h1 .hl{color:var(--blue);display:block} .hero h1 .dot{color:var(--ink)}
/* Desktop runs the whole headline on one line. The size scales with the
   viewport rather than being fixed, because at a fixed size the line would be
   long enough to reach the mascot on a narrow desktop: the artwork's left edge
   sits about 490px in at 901px wide and only moves right from there. */
/* Tablet keeps the stacked headline but scales it, so there is no jump from a
   fixed 60px at 900px to the single line that starts at 901px. */
@media(min-width:601px) and (max-width:900px){
  .hero h1{font-size:clamp(36px,5.4vw,50px)}
}
@media(min-width:901px){
  .hero h1{font-size:clamp(26px,3.2vw,48px);white-space:nowrap}
  .hero h1 .hl-lead{display:inline;font-size:1em;margin:0 .26em 0 0}
  .hero h1 .hl{display:inline}
}
.hero p{font-size:18px;color:var(--slate);max-width:460px;margin:20px 0 30px}
/* Selector has to out-specify `.hero p` above (0,1,1), or the 460px cap and
   18px size there win on specificity and this never applies. */
.hero p.hero-sub{max-width:none;width:100%;font-size:16.5px;line-height:1.55}
/* The mascot is solid above 900px and its left edge sits at roughly 490px in at
   901px, creeping right as the screen grows. Below a 1400px screen the
   paragraph is held to 460px so it always stops short of the artwork, which
   also settles it at three lines there. Wider than that the mascot has moved
   far enough right for the full 690px measure and two lines. */
@media(max-width:1400px){.hero p.hero-sub{max-width:460px}}
/* position anchors the suggestions panel that drops out of this bar. */
.hero-search{display:flex;align-items:center;background:#fff;border:1px solid var(--line);border-radius:40px;box-shadow:var(--shadow-lg);padding:8px 8px 8px 24px;max-width:540px;position:relative}
.hero-search input{flex:1;border:0;outline:0;font-size:16px;padding:15px 0;background:transparent;min-width:0;font-family:var(--sans)}
.hero-go{width:56px;height:56px;flex-shrink:0;border:0;border-radius:50%;background:var(--blue);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer}
.hero-go:hover{background:var(--blue-deep)}
.tags{display:flex;flex-wrap:wrap;gap:10px;margin-top:22px;align-items:center}
.tags .lbl{font-size:13px;color:var(--slate);font-weight:600;margin-right:2px}
.tag{font-size:13px;color:var(--ink-soft);background:#fff;border:1px solid var(--line);padding:8px 16px;border-radius:24px;font-weight:600}
/* On a phone the four tags wrapped differently depending on the exact screen
   width, sometimes 2 up, sometimes 3. A three column grid makes it the same
   everywhere: label on its own row, three tags, then the fourth beneath. */
@media(max-width:640px){
  .tags{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;align-items:stretch}
  .tags .lbl{grid-column:1/-1;margin:0 0 -2px}
  .tag{padding:8px 6px;font-size:12px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
}
.tag:hover{border-color:var(--blue);color:var(--blue)}


/* ── Category chips ──
   A mouse cannot swipe a rail and the scrollbar is deliberately hidden, so on a
   wide screen the whole set wraps and centres: every category is reachable and
   none of them has to be discovered. Narrow screens keep the rail, where the
   swipe is natural and the vertical space is worth more than the reveal. */
.chips{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;padding:22px 0}
.chip{display:flex;align-items:center;gap:9px;background:#fff;border:1px solid var(--line);border-radius:12px;padding:11px 16px;font-weight:600;font-size:13.5px;color:var(--ink-soft);cursor:pointer;transition:border-color .16s ease,color .16s ease,background .16s ease,transform .16s ease,box-shadow .16s ease}
.chip:hover{border-color:var(--blue);color:var(--blue);background:var(--blue-tint);transform:translateY(-2px);box-shadow:0 8px 20px rgba(31,82,255,.10)}
.chip .em{width:26px;height:26px;border-radius:8px;background:var(--blue-wash);color:var(--blue);display:flex;align-items:center;justify-content:center;flex-shrink:0}
/* The rail is gated on being able to swipe, not on width alone: a narrow
   desktop window is still a mouse, and a mouse cannot move a hidden-scrollbar
   rail. Anything that cannot hover gets the rail; everything else wraps. */
@media(max-width:900px) and (hover:none){
  .chips{flex-wrap:nowrap;justify-content:flex-start;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .chips::-webkit-scrollbar{display:none}
  .chip{flex-shrink:0}
  /* a lift under a fingertip only shifts the thing being tapped */
  .chip:hover{transform:none;box-shadow:none}
}
@media(prefers-reduced-motion:reduce){
  .chip{transition:border-color .16s ease,color .16s ease,background .16s ease}
  .chip:hover{transform:none}
}

/* ── Sections ── */
section{padding:52px 0}
.band{background:var(--blue-tint);border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft)}
/* The "see all" link sits on the heading's own line. A description belongs in
   .sec-sub underneath, never inside this row, or it would drag the link down
   and leave it out of line with the heading. */
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;margin-bottom:26px;gap:20px}
.sec-head:has(+.sec-sub){margin-bottom:8px}
.sec-sub{color:var(--slate);font-size:15px;margin:0 0 26px;max-width:640px}
.sec-head h2{font-size:30px;font-weight:800}
.sec-head p{color:var(--slate);font-size:15px;margin:6px 0 0}
.see-all{font-weight:700;font-size:14px;color:var(--blue);display:inline-flex;align-items:center;gap:6px}
.see-all:hover{gap:9px}
.tabs{display:flex;gap:8px;margin-bottom:24px;flex-wrap:wrap}
.tab{font-weight:600;font-size:13.5px;padding:9px 16px;border-radius:10px;border:1px solid var(--line);background:#fff;color:var(--slate);cursor:pointer}
.tab.on{background:var(--ink);color:#fff;border-color:var(--ink)}
.tab:not(.on):hover{border-color:#c9d2ea;color:var(--ink)}

/* product grid + card */
.grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:20px}
@media(max-width:1100px){.grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:820px){.grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:520px){.grid{grid-template-columns:1fr}}
.card{background:#fff;border:1px solid var(--line);border-radius:16px;overflow:hidden;display:flex;flex-direction:column;transition:transform .12s ease, box-shadow .12s ease, border-color .12s}
.card:hover{transform:translateY(-3px);box-shadow:var(--shadow-lg);border-color:#d4ddf5}
.thumb{aspect-ratio:16/10;position:relative;display:flex;align-items:center;justify-content:center}
.thumb .file{position:absolute;bottom:10px;left:10px;font-family:var(--mono);font-size:11px;color:#fff;background:rgba(0,0,0,.6);padding:4px 8px;border-radius:6px;backdrop-filter:blur(4px)}
.thumb .cat{position:absolute;top:10px;left:10px;font-family:var(--mono);font-size:10.5px;letter-spacing:.04em;color:#fff;background:rgba(0,0,0,.42);padding:4px 8px;border-radius:6px;text-transform:uppercase}
/* Placeholder tile when a product has no thumbnail: a white chip on the card's
   gradient, holding the category icon in the brand blue. */
.thumb .glyph{width:56px;height:56px;border-radius:15px;background:rgba(255,255,255,.92);color:var(--blue);display:flex;align-items:center;justify-content:center;box-shadow:0 8px 20px rgba(0,0,0,.2)}
.card-body{padding:15px 16px 0;flex:1;min-width:0}
/* Clamped to two lines so a long title cannot make one card taller than the
   rest of the row, and reserved at two lines so short titles align too. */
.card-body h3{font-size:15.5px;font-weight:700;line-height:1.35;letter-spacing:-.01em;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:2.7em}
/* The title link stretches over the whole card, so the card is clickable while
   the action buttons stay real, separately clickable controls. */
.card-link{display:block}
.card-link::after{content:"";position:absolute;inset:0;z-index:1}
.card-meta{display:flex;align-items:center;gap:6px;margin-top:9px;font-size:12.5px;color:var(--slate);min-width:0}
/* The vendor name is the only part allowed to shrink; it truncates rather than
   wrapping into a squashed column. The rating always keeps its full width. */
.card-meta .by{font-weight:600;color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;flex:0 1 auto}
.card-meta .sep{flex:0 0 auto;opacity:.5}
.rating{display:inline-flex;align-items:center;gap:4px;color:var(--amber);font-size:12.5px;flex:0 0 auto;white-space:nowrap}
.rating .c{color:var(--slate-light);font-family:var(--mono)}
.card-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:14px 16px;margin-top:14px;border-top:1px solid var(--line-soft)}
.card-foot .price{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* On a narrow card the extended price is the first thing to go, so the main
   price and the buttons always stay readable. */
@media(max-width:1150px){.card-foot .price .tier{display:none}}
.price{font-family:var(--mono);font-weight:700;font-size:17px;color:var(--ink)}
.price .free{color:var(--green)}
.tier{font-family:var(--mono);font-size:11px;color:var(--slate-light)}
/* Card actions sit above the stretched title link so they stay clickable. */
.card-actions{display:flex;align-items:center;gap:7px;position:relative;z-index:2;flex:0 0 auto}
.card-btn{width:38px;height:38px;border-radius:10px;display:flex;align-items:center;justify-content:center;cursor:pointer;border:1px solid transparent;flex-shrink:0;transition:background .12s,color .12s,border-color .12s}
.card-btn.add{background:var(--blue-wash);color:var(--blue)}
.card-btn.add:hover{background:var(--blue);color:#fff}
.card-btn.preview{background:#fff;border-color:var(--line);color:var(--slate)}
.card-btn.preview:hover{border-color:var(--blue);color:var(--blue);background:var(--blue-tint)}
.card{position:relative}
.card,.card *{text-decoration:none}
.card-link{color:inherit}
/* Keyboard focus has to show on the card, not just the invisible stretched
   link, so tabbing through a grid is followable. */
.card:has(.card-link:focus-visible){outline:2px solid var(--blue);outline-offset:2px}
.card-link:focus-visible{outline:none}
.card-btn:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.thumb-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* category chips are links */
a.chip{text-decoration:none}
/* empty states (no fake items when a section has no data) */
.empty{grid-column:1/-1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:46px 20px;background:var(--blue-tint);border:1px dashed var(--line);border-radius:16px;color:var(--slate);text-align:center}
/* Holds an SVG now rather than an emoji glyph, so no font-size and no opacity:
   the icons carry their own soft tone and dimming them muddied the blues. */
.empty-ic{line-height:1;display:flex;justify-content:center;margin-bottom:6px}
.empty-ic img{width:64px;height:64px;display:block}
@media(max-width:640px){.empty-ic img{width:56px;height:56px}}
.empty p{font-size:14px;max-width:360px;margin:0}
.empty-span2{grid-column:2 / -1}
@media(max-width:900px){.empty-span2{grid-column:1/-1}}

/* feature card (Picks) */
.picks{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:20px}
@media(max-width:900px){.picks{grid-template-columns:1fr 1fr}}
@media(max-width:520px){.picks{grid-template-columns:1fr}}
.feature{background:linear-gradient(150deg,#0b0b0e,#1c1c22);color:#fff;border-radius:18px;padding:28px;display:flex;flex-direction:column;justify-content:space-between;min-height:280px;position:relative;overflow:hidden}
.feature .badge{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:#8fb0ff}
.feature h3{font-size:26px;font-weight:800;margin-top:10px;line-height:1.1}
.feature p{color:#b9c2e4;font-size:14px;margin:12px 0 0;max-width:320px}
.feature .row{display:flex;align-items:center;gap:14px;margin-top:22px}
.feature .fp{font-family:var(--mono);font-weight:700;font-size:20px}
.feature .orb{position:absolute;width:220px;height:220px;border-radius:50%;background:radial-gradient(circle,rgba(31,82,255,.5),transparent 70%);right:-40px;top:-40px}
.feature .badge svg{color:var(--amber)}
.feature .fstats{display:flex;gap:26px;padding-top:20px;border-top:1px solid rgba(255,255,255,.12)}
.feature .fn{font-family:var(--mono);font-weight:800;font-size:22px;color:#fff;font-variant-numeric:tabular-nums}
.feature .fn span{color:#4f7cff}
.feature .fl{font-size:10.5px;text-transform:uppercase;letter-spacing:.08em;color:#8a8f9e;margin-top:2px}
.feature .fverified{display:flex;align-items:center;gap:8px;margin-top:16px;font-size:13px;font-weight:600;color:#3ddc97}

/* featured author */
.author{display:grid;grid-template-columns:300px 1fr;gap:28px;align-items:center}
.author-card{background:#fff;border:1px solid var(--line);border-radius:18px;padding:26px;text-align:center;box-shadow:var(--shadow)}
.author-cta{width:100%;justify-content:center}
.author-card .av{width:76px;height:76px;border-radius:20px;margin:0 auto 14px;background:linear-gradient(135deg,var(--blue),#7aa0ff);display:flex;align-items:center;justify-content:center;color:#fff;font-size:28px;font-weight:800}
.author-card h3{font-size:19px;font-weight:800}
.author-card .verified{color:var(--blue);font-size:13px;font-weight:600;margin-top:3px}
.author-stats{display:flex;justify-content:center;gap:22px;margin:18px 0}
.author-stats .n{font-weight:800;font-size:17px}
.author-stats .l{font-size:11.5px;color:var(--slate)}
/* Three fixed columns inside this already-narrow track squeezed each card to
   about 205px, which wrapped the vendor name and pushed titles to two lines.
   auto-fill keeps every card at a readable width and simply shows fewer of
   them when there is not room. */
.author-items{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:16px}
.author-items>*{min-width:0}

/* Below the desktop breakpoint the card becomes a banner above the items.
   Kept as a narrow column it sat beside a two-row grid of cards, so at 1024px a
   319px card faced a 744px list and left 425px of empty white next to it. Across
   the top it is the same information with nothing wasted, and the items get the
   full width, which fits three across instead of two. */
@media(max-width:1100px){
  .author{grid-template-columns:1fr;gap:20px}
  .author-card{display:flex;align-items:center;gap:18px;flex-wrap:wrap;text-align:left;padding:18px 22px}
  .author-card .av{width:58px;height:58px;border-radius:16px;margin:0;font-size:21px;flex-shrink:0}
  .author-id{flex:1;min-width:150px}
  .author-stats{margin:0;justify-content:flex-start;gap:26px;flex-shrink:0}
  .author-cta{width:auto;flex-shrink:0}
}
/* Narrow phones: the row has run out of width, so it goes back to a column. */
@media(max-width:600px){
  .author-items{grid-template-columns:1fr}
  .author-card{display:block;text-align:center;padding:24px}
  .author-card .av{margin:0 auto 14px;width:70px;height:70px;font-size:26px}
  .author-stats{justify-content:center;margin:16px 0}
}

/* testimonials */
.quotes{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
@media(max-width:900px){.quotes{grid-template-columns:1fr}}
.quote{background:#fff;border:1px solid var(--line);border-radius:16px;padding:24px;box-shadow:var(--shadow)}
.quote .stars{color:var(--amber);font-size:14px}
.quote p{font-size:14.5px;color:var(--ink-soft);margin:12px 0 18px;line-height:1.6}
.quote .who{display:flex;align-items:center;gap:11px}
.quote .who .av{width:40px;height:40px;border-radius:11px;background:var(--blue-wash);color:var(--blue);display:flex;align-items:center;justify-content:center;font-weight:700}
.quote .who .nm{font-weight:700;font-size:13.5px}
.quote .who .rl{font-size:12px;color:var(--slate)}

/* faq */
.faq{max-width:760px;margin:0 auto}
.faq-item{border-bottom:1px solid var(--line)}
.faq-q{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:20px 4px;cursor:pointer;font-weight:700;font-size:16px}
.faq-q .pl{color:var(--blue);font-size:20px;transition:transform .2s}
.faq-item.open .faq-q .pl{transform:rotate(45deg)}
.faq-a{max-height:0;overflow:hidden;transition:max-height .25s ease;color:var(--slate);font-size:14.5px;line-height:1.65}
.faq-item.open .faq-a{max-height:220px;padding:0 4px 20px}

/* seller CTA */
.seller{background:linear-gradient(150deg,var(--blue),var(--blue-deep));border-radius:22px;padding:48px;color:#fff;display:flex;align-items:center;justify-content:space-between;gap:30px;flex-wrap:wrap;position:relative;overflow:hidden}
.seller h2{font-size:32px;font-weight:800;max-width:520px}
.seller p{color:#d5e0ff;margin:12px 0 0;max-width:480px;font-size:15px}
.seller .orb{position:absolute;width:300px;height:300px;border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,.18),transparent 70%);right:-60px;bottom:-120px}

/* footer */
/* The bottom pad grows by the phone's safe area, so the footer's black runs all
   the way under the home indicator instead of stopping short and leaving a
   white band there. env() resolves to 0 on anything without an inset. */
/* ── The CTA that straddles the page/footer seam ──
   The band carries the page white down to the card. The card's negative bottom
   margin lifts the footer up under it, so the overlap is the card's lower
   portion, and z-index keeps the card above the black. */
.foot-cta-band{background:var(--white);position:relative;z-index:2;padding-top:20px}
/* Shares the footer columns' 1120px measure, so the card and the footer below
   line up on the same edges instead of the card running wider. */
.foot-cta{position:relative;z-index:3;max-width:1120px;margin:0 auto -78px;
  background:linear-gradient(150deg,var(--blue),var(--blue-deep));border-radius:30px;padding:44px 48px;color:#fff;
  display:flex;align-items:center;justify-content:space-between;gap:30px;flex-wrap:wrap;overflow:hidden;
  box-shadow:0 24px 60px rgba(11,57,214,.28)}
.foot-cta .orb{position:absolute;width:320px;height:320px;border-radius:50%;
  background:radial-gradient(circle,rgba(255,255,255,.18),transparent 70%);right:-70px;bottom:-130px}
/* ── 3D depth behind the CTA ──
   A grid floor laid back in perspective, plus glass tiles tilted on two axes.
   The lighting is faked with a top-down gradient, a bright inset top edge and a
   drop shadow, which is what sells them as solid objects rather than flat
   squares. All of it sits behind the copy. */
.cta3d{position:absolute;inset:0;perspective:900px;pointer-events:none;overflow:hidden;z-index:0}
.cta-floor{position:absolute;left:-10%;right:-10%;bottom:-42%;height:85%;
  background-image:linear-gradient(rgba(255,255,255,.14) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.14) 1px,transparent 1px);
  background-size:46px 46px;
  transform:rotateX(72deg);transform-origin:50% 100%;
  -webkit-mask-image:linear-gradient(to top,#000,transparent 72%);
  mask-image:linear-gradient(to top,#000,transparent 72%)}
.cta-tile{position:absolute;display:flex;align-items:center;justify-content:center;color:#fff;
  border-radius:20px;border:1px solid rgba(255,255,255,.30);
  background:linear-gradient(150deg,rgba(255,255,255,.32),rgba(255,255,255,.07));
  box-shadow:0 20px 38px rgba(3,10,45,.34),inset 0 1.5px 0 rgba(255,255,255,.5);
  animation:ctafloat 7s ease-in-out infinite}
/* Kept inside the gap between the copy and the button, so nothing sits behind
   the call to action. */
.cta-tile.t1{width:86px;height:86px;right:26%;top:10%;transform:rotateX(16deg) rotateY(-24deg) rotate(-8deg)}
.cta-tile.t2{width:62px;height:62px;right:40%;top:54%;transform:rotateX(18deg) rotateY(-20deg) rotate(9deg);animation-delay:-2.3s}
.cta-tile.t3{width:52px;height:52px;right:33%;top:62%;transform:rotateX(14deg) rotateY(-26deg) rotate(-14deg);animation-delay:-4.6s}
.cta-coin{position:absolute;right:23%;top:62%;width:56px;height:56px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-family:var(--mono);font-weight:800;font-size:22px;color:#0b39d6;
  background:linear-gradient(150deg,#fff,#cfdcff);
  box-shadow:0 16px 32px rgba(3,10,45,.36),inset 0 -3px 6px rgba(11,57,214,.25),inset 0 2px 0 #fff;
  animation:ctafloat 7s ease-in-out infinite;animation-delay:-1.2s}
@keyframes ctafloat{0%,100%{translate:0 0}50%{translate:0 -12px}}
@media(prefers-reduced-motion:reduce){.cta-tile,.cta-coin{animation:none}}
/* On a stacked card the copy runs the full width, so the props move up into the
   top-right corner and shrink, and the two that would land behind the text are
   dropped rather than crowding it. */
/* On a stacked card the copy runs the full width, so the props move up into the
   top-right corner, shrink, and the two that would land behind the text are
   dropped. The copy gets matching right padding so the headline stops before
   them instead of running underneath. */
/* A stacked card has no room for floating props beside the copy: they either
   crowd the headline or force it onto two lines. On these sizes the depth comes
   purely from the background instead, a receding grid floor and a large tilted
   panel, so the text keeps the full width and the card stays short. */
@media(max-width:900px){
  .foot-cta-copy{padding-right:0}
  .cta-tile,.cta-coin{display:none}
  .cta-floor{bottom:-46%;height:82%;background-size:38px 38px;
    background-image:linear-gradient(rgba(255,255,255,.20) 1px,transparent 1px),
                     linear-gradient(90deg,rgba(255,255,255,.20) 1px,transparent 1px)}
  .cta3d::after{content:"";position:absolute;right:-18%;top:-30%;width:78%;aspect-ratio:1;
    border-radius:34%;background:linear-gradient(150deg,rgba(255,255,255,.16),rgba(255,255,255,0) 62%);
    transform:rotate(24deg)}
}

.foot-cta-copy{position:relative;z-index:1;min-width:0}
/* No max-width: the 19ch cap was breaking the headline onto two lines even
   though there was room for it in one.
   The single-line rule is scoped to wide screens with min-width rather than
   being overridden later, because a plain override further up the file loses to
   this declaration on source order and the headline then overflows the card. */
.foot-cta h2{font-size:30px;font-weight:800;letter-spacing:-.02em;text-wrap:balance}
@media(min-width:901px){.foot-cta h2{text-wrap:nowrap}}
.foot-cta p{color:#d5e0ff;margin:12px 0 0;max-width:52ch;font-size:15px;line-height:1.6}
.foot-cta-btn{position:relative;background:#fff;color:var(--blue);padding:15px 30px;font-size:15px;flex-shrink:0}
.foot-cta-btn:hover{background:#eef2ff}

/* margin-top removed on purpose: it let the black body show through as a hard
   16px band above the footer, which read as a stray line. The extra top padding
   clears the CTA card overlapping into this space. */
footer{background:var(--black);color:#9a9aa2;padding:134px 0 calc(28px + env(safe-area-inset-bottom));margin-top:0}
/* Full-bleed black, but the columns stay a centred group rather than stretching
   across the whole of a wide monitor. */
/* Brand block plus four link columns. The brand gets the wider track because it
   carries the logo and a sentence, not a list. */
.foot-grid{display:grid;grid-template-columns:1.7fr repeat(4,1fr);gap:30px;max-width:1200px;margin:0 auto}
/* Without min-width:0 the brand column cannot shrink below the logo's own
   width, which steals space from the link columns and pushes the page wide. */
.foot-grid>*{min-width:0}
@media(max-width:1080px){
  /* Four link columns will not hold their headings on one line much below this,
     so they drop to two and the brand spans the row above them. */
  .foot-grid{grid-template-columns:1fr 1fr;gap:30px 36px}
  .foot-grid>:first-child{grid-column:1/-1}
}
@media(max-width:820px){
  .foot-cta{padding:26px 22px;border-radius:24px;margin:0 auto -58px;gap:18px}
  /* Sized to hold the headline on one line right down to a 320px screen: the
     clamp scales it with the viewport so it never has to wrap. */
  .foot-cta h2{font-size:clamp(16px,5.3vw,25px);white-space:nowrap;max-width:none}
  .foot-cta p{font-size:13.5px;margin-top:9px}
  .foot-cta-btn{width:auto;align-self:flex-start;padding:13px 26px}
  footer{padding-top:104px}
}
/* Phones keep the two columns rather than stacking: four lists in one column is
   a long scroll past links nobody is reading. The brand spans the row above, so
   nothing is squeezed by sharing the width. */
@media(max-width:520px){
  .foot-grid{grid-template-columns:1fr 1fr;gap:26px 20px}
  .foot-cta{padding:24px 20px;margin:0 auto -48px;gap:16px}
  .foot-cta p{font-size:13px;line-height:1.55}
  footer{padding-top:92px}
}
/* Narrowest phones: the headings still fit two up, the gap is what gives. */
@media(max-width:360px){
  .foot-grid{gap:22px 14px}
}
/* Stacked on a phone, the copyright and ownership lines centre rather than
   sitting flush left where the space-between leaves them ragged. */
@media(max-width:640px){
  .foot-bottom{flex-direction:column;justify-content:center;text-align:center;gap:10px}
}
footer .logo .a{color:#fff}
footer p.tagline{color:#7a7a82;font-size:13.5px;margin:14px 0 0;max-width:280px;line-height:1.6}
footer h4{color:#fff;font-size:13px;text-transform:uppercase;letter-spacing:.08em;margin:0 0 16px;font-family:var(--mono)}
footer ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px}
footer a{color:#9a9aa2;font-size:13.5px}
footer a:hover{color:#fff}
.foot-bottom{display:flex;align-items:center;justify-content:space-between;max-width:1120px;margin:40px auto 0;padding-top:22px;border-top:1px solid rgba(255,255,255,.1);gap:16px;flex-wrap:wrap}
.foot-bottom .pb{font-size:13px;color:#7a7a82}
.foot-bottom .pb b{color:var(--blue);font-weight:700}
.slot-note{font-family:var(--mono);font-size:10px;color:var(--slate-light);letter-spacing:.05em}
.owned{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:#6a6a72}

/* ── Collapsible mobile search ── */
/* Slides open rather than appearing.
   The row track animates from 0fr to 1fr, which eases the bar's ACTUAL height.
   max-height cannot: it needs a ceiling above the real height, so the bar hits
   full size part way through and the rest of the easing plays out invisibly,
   which reads as a snap rather than a slide.
   The content is lifted in as well, so it arrives from behind the header
   instead of the panel merely growing. */
.mobile-search{background:var(--black);display:grid;grid-template-rows:0fr;opacity:0;
  transition:grid-template-rows .34s cubic-bezier(.22,.8,.28,1),opacity .24s ease}
/* Clipping belongs on the child for this to work, and min-width/height:0 is
   what lets a grid item actually shrink to nothing. */
/* No padding here: at a zero track the box collapses but its padding still
   renders, so the bar would open from 14px instead of nothing and snap that
   distance before the slide began. The spacing sits on the form instead, inside
   the clipped area, where it collapses with everything else. */
/* width:100% is load-bearing. As a grid item, .wrap's own `margin:0 auto`
   overrides the default stretch, so it sized to its content and centred, which
   left the bar a narrow strip with black either side. It was a plain block
   before the animation, where those auto margins did nothing. */
.mobile-search>.wrap{width:100%;overflow:hidden;min-height:0;
  transform:translateY(-12px);opacity:.4;
  transition:transform .34s cubic-bezier(.22,.8,.28,1),opacity .28s ease}
.mobile-search>.wrap>.search{margin-bottom:14px}
.mobile-search.on{grid-template-rows:1fr;opacity:1}
.mobile-search.on>.wrap{transform:none;opacity:1}
/* Once open the clipping has to go, or the suggestions dropdown hanging below
   the bar would be cut off at its edge. */
.mobile-search.done>.wrap{overflow:visible}
.mobile-search .search{max-width:100%;height:46px}
@media(prefers-reduced-motion:reduce){
  .mobile-search,.mobile-search>.wrap{transition-duration:.01s}
}
/* off-canvas mobile menu */
.m-overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);opacity:0;visibility:hidden;transition:opacity .25s;z-index:60}
.m-overlay.on{opacity:1;visibility:visible}
.m-menu{position:fixed;top:0;left:0;bottom:0;width:290px;max-width:86vw;background:#fff;z-index:70;transform:translateX(-100%);transition:transform .28s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;box-shadow:0 0 60px rgba(0,0,0,.2)}
.m-menu.on{transform:none}
.m-menu-head{display:flex;align-items:center;justify-content:space-between;padding:18px 20px;border-bottom:1px solid var(--line)}
.m-menu-head .logo{font-size:19px}
.m-close{width:40px;height:40px;border:0;background:transparent;color:var(--slate);cursor:pointer;display:flex;align-items:center;justify-content:center}
.m-links{flex:1;padding:12px 12px calc(12px + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:2px;overflow-y:auto}
.m-links a{display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:9px;font-weight:500;font-size:14px;color:var(--ink)}
.m-links a:hover,.m-links a:active{background:var(--blue-tint);color:var(--blue)}
.m-links .mi{width:20px;display:flex;align-items:center;justify-content:center;color:var(--slate);flex-shrink:0}
.m-links a:hover .mi,.m-links a:active .mi{color:var(--blue)}
.m-links .m-free .mi{color:var(--green)}
/* The cross-sell to domzivo.com carries the longest label in the menu and was
   wrapping onto two lines on every phone. It is a secondary promo, so it takes
   a smaller type size and a tighter icon, and is pinned to one line at any
   width, truncating rather than wrapping if a device is narrower still. */
.m-links .m-cross{font-size:12.5px;padding:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--slate);margin-top:4px;border-top:1px solid var(--line-soft);border-radius:0}
.m-links .m-cross:hover,.m-links .m-cross:active{background:var(--blue-tint);color:var(--blue)}
.m-auth{padding:16px 16px calc(22px + env(safe-area-inset-bottom));border-top:1px solid var(--line);display:flex;flex-direction:column;gap:10px}
body.menu-lock{overflow:hidden}

/* ── Hero on small screens ── */
/* Matched to the 901px point where the headline stops being one line. At 820 it
   left an 821-900 band where the mascot was still solid but the headline had
   already stacked and grown, so the copy ran straight into the artwork. */
@media(max-width:900px){
  .hero-mascot{opacity:.22;width:80%;max-width:none}
}
@media(max-width:600px){
  .hero-inner{padding:36px 0 40px;max-width:100%}
  /* Scales with the viewport so the headline keeps clearance on a 320px screen
     rather than sitting a couple of pixels off the edge at a fixed 36px. */
  .hero h1{font-size:clamp(24px,8vw,36px)}
  .hero p{font-size:16px;margin:16px 0 24px}
  .hero-search{max-width:100%}
  .hero-search input{font-size:15px;padding:13px 0}
  .hero-go{width:50px;height:50px}
  .hero-badge{font-size:10px}
  .sec-head h2{font-size:24px}
  .sec-head{margin-bottom:20px}
  section{padding:40px 0}
  .announce{font-size:11px;padding:8px 12px}
  .wrap{padding:0 18px}
  .feature .fstats{gap:20px}
}

/* ═══ Header refinements to match the reference ═══ */

/* Top utility bar */
.topbar{display:block;background:var(--black);border-bottom:1px solid rgba(255,255,255,.07)}
.topbar-in{display:flex;align-items:center;justify-content:space-between;height:40px}
.tb-left,.tb-right{display:flex;align-items:center;gap:22px}
.tb-left span,.tb-left a,.tb-right a{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:#b0b0ba;font-weight:500;white-space:nowrap}
.tb-left span svg,.tb-left a svg,.tb-right a svg{color:#787884}
.tb-left span:first-child svg{color:var(--blue)}
.tb-right a:hover,.tb-left a:hover{color:#fff}
.tb-right a:hover svg,.tb-left a:hover svg{color:var(--blue)}
/* The cross-sell to domzivo.com is the one actionable item on the left, so it
   reads as a link rather than blending into the assurances beside it. */
.tb-cross{color:#cfd4e6 !important;font-weight:600 !important}
.tb-cross svg{color:var(--blue) !important}
.tb-cross:hover{color:#fff !important;text-decoration:underline}

/* Header search: All Categories | input | square button */
/* Centred in the bar rather than left-aligned next to the logo: the auto side
   margins push it to the middle of whatever space the logo and actions leave. */
/* position anchors the suggestions panel. overflow is visible rather than
   hidden because that panel hangs below the bar: the button is inset with its
   own radius further down, so nothing needs clipping to the rounded corners. */
.search{flex:1 1 740px;max-width:740px;margin:0 auto;display:flex;align-items:stretch;background:#fff;border:0;border-radius:11px;height:46px;min-width:0;overflow:visible;position:relative;padding:0}
.search:focus-within{box-shadow:0 0 0 3px rgba(31,82,255,.3)}
.search-cats{display:flex;align-items:center;gap:6px;padding:0 16px;background:transparent;border:0;border-right:1px solid var(--line);color:var(--ink-soft);font-weight:600;font-size:13.5px;white-space:nowrap;cursor:pointer;flex-shrink:0}
.search-cats:hover{color:var(--blue)}
.search input{flex:1;border:0;outline:0;font-size:14.5px;padding:0 16px;min-width:0;background:transparent;color:var(--ink);font-family:var(--sans)}
.search .search-go{width:56px;flex-shrink:0;border:0;border-radius:0;background:var(--blue);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer}
.search .search-go:hover{background:var(--blue-deep)}
/* The collapsible bar matches the header search height on the same screens. */
.mobile-search .search{padding:0 6px 0 14px;align-items:center;height:42px}
.mobile-search .search svg{color:var(--slate-light);flex-shrink:0}
.mobile-search .search input{padding:0 8px}

/* ============ Page loading line ============ */
/* Sits above everything, including the sticky header and any open menu, so it
   is never the thing that gets covered up. */
.pgb{position:fixed;top:0;left:0;right:0;height:3px;z-index:9999;pointer-events:none;
  opacity:0;transition:opacity .2s ease}
.pgb.on{opacity:1}
/* scaleX rather than width: it animates on the compositor, so the line stays
   smooth even while the browser is busy parsing the next page. */
.pgb-fill{display:block;height:100%;width:100%;transform:scaleX(0);transform-origin:0 50%;
  background:linear-gradient(90deg,var(--blue) 0%,#5b8bff 60%,var(--blue) 100%);
  box-shadow:0 0 10px rgba(31,82,255,.7),0 0 4px rgba(31,82,255,.5);
  transition:transform .32s cubic-bezier(.25,.8,.3,1)}
/* The last stretch snaps shut, so finishing feels like an arrival. */
.pgb.done .pgb-fill{transition:transform .18s ease-out}
.pgb.done{opacity:0;transition:opacity .28s ease .12s}

@media(prefers-reduced-motion:reduce){
  .pgb-fill{transition:transform .12s linear}
  .pgb,.pgb.done{transition:opacity .1s linear}
}

/* ============ Search suggestions ============ */
/* Hangs below the search bar while someone is still typing. */
.sg{position:absolute;top:calc(100% + 8px);left:0;right:0;z-index:120;
  background:#fff;border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow-lg);
  overflow:hidden auto;max-height:min(70vh,460px);padding:6px;text-align:left}
.sg-head{font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--slate-light);padding:9px 11px 6px}
.sg-row{display:flex;align-items:center;gap:11px;padding:8px 11px;border-radius:10px;
  color:var(--ink);cursor:pointer}
/* Both states styled the same, so a mouse and the arrow keys agree on what is
   about to be opened. */
.sg-row:hover,.sg-row.on{background:var(--blue-tint)}
.sg-thumb{width:46px;height:32px;flex-shrink:0;border-radius:7px;object-fit:cover;
  border:1px solid var(--line-soft);background:var(--blue-tint)}
.sg-thumb-none{display:block}
.sg-ico{width:30px;height:30px;flex-shrink:0;border-radius:8px;background:var(--blue-wash);
  color:var(--blue-deep);display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700}
.sg-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.sg-name{font-size:13.5px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The typed part, so it is obvious why a row matched. */
.sg-name b{color:var(--blue);font-weight:800}
.sg-meta{font-size:11.5px;color:var(--slate);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sg-right{flex-shrink:0;display:flex;align-items:center;gap:9px;font-family:var(--mono);
  font-size:12.5px;font-weight:700}
.sg-free{color:#0a7048;background:var(--green-wash);border-radius:20px;padding:2px 8px;font-size:11px}
.sg-rate{color:var(--amber);font-size:11.5px}
.sg-rate::before{content:"★ "}
.sg-cat .sg-name{font-weight:700}
.sg-all{justify-content:center;font-size:12.5px;font-weight:700;color:var(--blue);
  margin-top:4px;border-top:1px solid var(--line-soft);border-radius:0 0 9px 9px;padding-top:12px}
.sg-empty{padding:22px 14px;text-align:center;font-size:13px;color:var(--slate)}

@media(max-width:600px){
  .sg{max-height:min(60vh,380px)}
  .sg-thumb{width:40px;height:28px}
  .sg-right{font-size:11.5px}
}

/* Category row: icon + label + caret, plus highlighted pills */
.nav-cats-in{gap:2px}
/* The visible space between two labels is both paddings plus the gap, so at
   16px padding they sat 36px apart and read as a scattered row rather than one
   menu. Tightened to 24px, which still gives each its own hover target. */
.cat-links{gap:2px}
/* Direct children only. Unscoped, these matched the links INSIDE the flyout
   too, since it is nested in .cat-links: the hover rule painted them #fff on a
   white panel, so a subcategory disappeared the moment you pointed at it. */
.cat-links > a,.cat-item > a{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:500;color:#b3b3bd;padding:6px 8px;border-radius:7px;white-space:nowrap}
.cat-links > a svg,.cat-item > a svg{color:#8a8f9e}
.cat-links > a:hover,.cat-item > a:hover{color:#fff;background:rgba(255,255,255,.07)}
.cat-links > a:hover svg,.cat-item > a:hover svg{color:var(--blue)}
.cat-links .cv{width:6px;height:6px;border:solid currentColor;border-width:0 1.5px 1.5px 0;transform:rotate(45deg);opacity:.4;margin:-3px 0 0 1px}
.cat-flex{flex:1}
.cat-pill{color:#fff !important;font-weight:700 !important;padding:10px 16px !important}
/* Just above the mobile breakpoint the full set would not fit at the larger
   size, so it tightens rather than starting to scroll. */
/* The full-size row needs about 1305px for all ten items, so the tighter
   styling has to start above that, not at 1250: between the two the row
   overflowed at 1280px, one of the most common laptop widths. */
@media(max-width:1320px){
  .cat-links > a,.cat-item > a{font-size:12px;padding:6px 7px;gap:5px}
  .cat-pill{padding:9px 13px !important}
}
.cat-pill svg{color:#fff !important}
.cat-free{background:var(--green)}
.cat-free:hover{background:#0fa06f !important}
.cat-sell{background:linear-gradient(135deg,#f5a524,#e8890b)}
.cat-sell:hover{filter:brightness(1.06)}
@media(max-width:1100px){.topbar{display:none}}

/* ═══ Hero mascot floating badges ═══ */
.mascot-stage{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center}
/* ── Hero background depth ──
   Light pools behind the artwork, then a grid floor laid back in perspective
   with a bright horizon line where it meets the page. This is what gives the
   scene somewhere to sit, instead of the mascot floating on flat white. */
.hero-bg3d{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.hb-glow{position:absolute;border-radius:50%;filter:blur(70px)}
.hb-glow.g1{width:46%;aspect-ratio:1;right:2%;top:-14%;background:radial-gradient(circle,rgba(47,92,255,.30),transparent 68%)}
.hb-glow.g2{width:34%;aspect-ratio:1;right:22%;bottom:-16%;background:radial-gradient(circle,rgba(0,208,255,.22),transparent 66%)}
.hb-glow.g3{width:30%;aspect-ratio:1;left:-8%;top:24%;background:radial-gradient(circle,rgba(124,58,237,.14),transparent 68%)}
.hb-grid{position:absolute;left:-25%;right:-25%;bottom:0;height:46%;
  background-image:linear-gradient(rgba(31,82,255,.26) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(31,82,255,.26) 1px,transparent 1px);
  background-size:64px 64px;
  transform:perspective(620px) rotateX(74deg);transform-origin:50% 100%;
  -webkit-mask-image:linear-gradient(to top,#000 0%,transparent 78%);
  mask-image:linear-gradient(to top,#000 0%,transparent 78%)}
/* Confined to the right half, behind the artwork. Run full width it crossed the
   headline and paragraph as a stray rule. */
.hb-horizon{position:absolute;left:52%;right:0;bottom:34%;height:1px;
  background:linear-gradient(90deg,transparent,rgba(47,92,255,.40),transparent);
  box-shadow:0 0 30px 6px rgba(47,92,255,.16)}

/* Floating props, rebuilt as glass rather than flat white discs: a graded
   surface, a lit top edge, a coloured shadow with real falloff, and a slight
   tilt on two axes so they read as objects in the scene. */
.fb{position:absolute;display:flex;align-items:center;justify-content:center;z-index:3;
  border-radius:22px;border:1px solid rgba(255,255,255,.85);
  background:linear-gradient(145deg,rgba(255,255,255,.96),rgba(233,240,255,.72));
  box-shadow:0 26px 48px -14px rgba(10,22,80,.30),
             0 8px 16px -8px rgba(10,22,80,.20),
             inset 0 1.5px 0 rgba(255,255,255,1),
             inset 0 -3px 8px rgba(120,150,255,.20);
  backdrop-filter:blur(9px) saturate(150%);-webkit-backdrop-filter:blur(9px) saturate(150%);
  animation:fbfloat 8s ease-in-out infinite}
@keyframes fbfloat{0%,100%{translate:0 0}50%{translate:0 -14px}}
@media(prefers-reduced-motion:reduce){.fb{animation:none}}
/* Each tilted differently and offset in the float cycle, so they read as
   separate objects rather than one rigid set. */
.fb-a,.fb-b,.fb-c,.fb-d{width:64px;height:64px}
.fb-a{top:15%;left:5%;color:var(--amber);transform:rotate(-7deg) rotateX(12deg) rotateY(14deg);animation-delay:-1.1s}
.fb-b{top:9%;right:7%;color:var(--green);transform:rotate(6deg) rotateX(12deg) rotateY(-14deg);animation-delay:-3.4s}
.fb-c{top:46%;left:-2%;color:var(--blue);transform:rotate(-11deg) rotateX(10deg) rotateY(16deg);animation-delay:-5.6s}
.fb-d{bottom:19%;right:1%;color:var(--ink);transform:rotate(9deg) rotateX(10deg) rotateY(-16deg);animation-delay:-2.2s}
/* The rating pill stays a pill, and reads as the brightest object in the scene. */
/* A soft contact shadow under the mascot, so it sits on the grid floor rather
   than hovering over it. */
.mascot-stage::after{content:"";position:absolute;left:14%;right:14%;bottom:6%;height:34px;border-radius:50%;
  background:radial-gradient(ellipse at center,rgba(10,22,80,.26),transparent 70%);filter:blur(10px);z-index:1}
.fb-coin{width:88px;height:88px;bottom:10%;left:2%;transform:rotate(-5deg) rotateX(10deg) rotateY(12deg);animation-delay:-4.3s}
@media(max-width:900px){.fb{display:none}}

/* ═══ Logo image (with text fallback) ═══ */
/* Never shrinks. The search bar asks for a wide flex-basis, and without this
   the logo was the thing that gave way, collapsing to nothing below 1100px. */
.logo{display:inline-flex;align-items:center;gap:0;flex-shrink:0}
/* The mark is a two-line lockup (wordmark over "Powered by Domzivo"), so it
   needs less height than a single-line wordmark would at the same weight. */
.logo-img{height:32px;width:auto;max-width:100%;aspect-ratio:977/160;display:block;object-fit:contain}
.logo-text{display:none;font-size:22px;font-weight:800;letter-spacing:-.03em;white-space:nowrap}
.logo-text .a{color:#fff} .logo-text .b{color:#4f7cff}
.logo-fallback .logo-img{display:none}
.logo-fallback .logo-text{display:inline-block}
/* The mark is white, so it only ever sits on the dark header, footer and menu. */
footer .logo-img{height:36px}
.m-menu-head .logo-img{height:28px}
/* footer + menu logos sit on light/dark grounds; keep the text crisp there */
footer .logo-text .a,.m-menu .logo-text .a{color:inherit}

/* ═══ Search button: inset, rounded (not a hard full-height square) ═══ */
.search{padding:5px}
.search .search-go{width:40px;height:34px;border-radius:8px;align-self:center}
.search .search-go svg{width:16px;height:16px}

/* ═══ Category row stays a block; hidden below the desktop breakpoint ═══ */
.nav-cats-row{display:block}

/* ═══ Hero mascot image (with placeholder fallback) ═══ */
.mascot-img{width:92%;height:auto;aspect-ratio:699/795;max-height:100%;object-fit:contain;position:relative;z-index:2;filter:drop-shadow(0 30px 50px rgba(10,17,48,.18))}
.mascot-stage .mascot-slot{display:none}
.mascot-stage.mascot-fallback .mascot-img{display:none}
.mascot-stage.mascot-fallback .mascot-slot{display:flex}

/* ═══ Phone and tablet header ═══ */
/* Below the category breakpoint the hamburger takes the far left, so the logo
   shrinks to leave room for it alongside the cart and account icons, and the
   search bar comes down in height so it stops dominating the row. */
@media(max-width:1100px){
  .nav-in{gap:12px;height:64px}
  .logo-img{height:27px}
  /* Tablet only: pull the menu button ahead of the logo, so it balances the
     inline search bar sitting in the middle of the row. Phones keep it in DOM
     order, which puts it at the far right beside the cart and account. */
  @media(min-width:721px){
    #menu-open{order:-1;margin-right:2px}
  }
  .search{height:42px;border-radius:10px;padding:5px}
  .search input{padding:0 12px}
  .search .search-go{width:38px;height:32px;border-radius:8px}
  .search .search-go svg{width:16px;height:16px}
  .search-cats{height:32px;padding-left:10px;font-size:12.5px}
}

/* ═══ Compress the header icons on very small phones ═══ */
@media(max-width:430px){
  .nav-in{gap:8px}
  .logo-img{height:23px}
  .logo-text{font-size:18px}
  .nav-actions{gap:6px}
  .icon-btn{width:38px;height:38px}
  .wrap{padding:0 14px}
}

/* ============ Storefront inner pages ============ */
/* breadcrumbs */
.crumbs{font-size:12.5px;color:var(--slate-light);padding:26px 0 4px;display:flex;flex-wrap:wrap;gap:7px;align-items:center}
.crumbs a{color:var(--slate)}
.crumbs a:hover{color:var(--blue)}
.crumbs span{opacity:.5}

/* ---- Browse / category / search ---- */
.browse{padding:8px 0 60px}
.browse-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;margin:6px 0 20px}
.browse-head h1{font-size:32px;font-weight:800;letter-spacing:-.02em}
.browse-sub{color:var(--slate);font-size:14.5px;margin-top:6px}
.sortbar{display:flex;align-items:center;gap:9px;flex-shrink:0}
.sortlbl{font-size:13px;color:var(--slate);font-weight:600}
.sortsel{font:inherit;font-size:13.5px;font-weight:600;color:var(--ink);background:#fff;border:1px solid var(--line);border-radius:10px;padding:9px 12px;cursor:pointer;max-width:100%}
/* The heading and the search box cannot sit side by side much below a laptop:
   the box is 340px, so at 700px it leaves the title about 250px and the two
   collide. 520 was the old breakpoint, from when this row held a small select
   rather than a search field. */
@media(max-width:820px){
  .browse-head{flex-direction:column;align-items:stretch;gap:14px}
  .browse-head .items-search{flex:1 1 auto;width:100%}
}
.sortsel:focus{outline:none;border-color:var(--blue)}
.filter-cats{display:flex;flex-wrap:wrap;gap:9px;margin-bottom:26px}
.filter-pill{display:inline-flex;align-items:center;gap:7px;background:#fff;border:1px solid var(--line);border-radius:30px;padding:8px 15px;font-size:13px;font-weight:600;color:var(--ink-soft)}
.filter-pill:hover{border-color:var(--blue);color:var(--blue)}
.filter-pill.on{background:var(--ink);border-color:var(--ink);color:#fff}
.filter-pill.free{color:var(--green)}
.filter-pill.free.on{background:var(--green);border-color:var(--green);color:#fff}
.filter-pill .fp-n{font-family:var(--mono);font-size:11px;opacity:.7}
/* pagination */
.pagination{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin-top:40px}
.page{min-width:40px;height:40px;padding:0 12px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--line);border-radius:10px;background:#fff;font-weight:700;font-size:13.5px;color:var(--ink-soft)}
.page:hover{border-color:var(--blue);color:var(--blue)}
.page.on{background:var(--blue);border-color:var(--blue);color:#fff}
.page.nav{color:var(--slate)}

/* ---- Product detail ---- */
.pd{padding:8px 0 70px}

.pd-hero{padding:4px 0 20px;border-bottom:1px solid var(--line);margin-bottom:24px}
.pd-hero h1{font-size:clamp(22px,2.8vw,31px);font-weight:800;letter-spacing:-.025em;line-height:1.2}
.pd-meta{display:flex;align-items:center;gap:9px 18px;margin-top:12px;flex-wrap:wrap;font-size:13.5px}
.pd-by{display:inline-flex;align-items:center;gap:8px;color:var(--slate)}
.pd-by b{color:var(--ink);font-weight:700}
.pd-by:hover b{color:var(--blue)}
.pd-by-av{width:25px;height:25px;border-radius:50%;background:linear-gradient(135deg,var(--blue),#7aa0ff);color:#fff;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:800}
.pd-rate{display:inline-flex;align-items:center;gap:6px}
.pd-rate-n{font-weight:700;color:var(--ink)}
.pd-rate-c{color:var(--slate-light);font-size:12.5px}
.pd-rate:hover .pd-rate-n{color:var(--blue)}
.pd-stat{color:var(--slate);font-family:var(--mono);font-size:12.5px}

/* Source order is the phone order: preview, buy, then the detail. Desktop
   places the same blocks into two columns with a sticky purchase panel. */
.pd-grid{display:grid;grid-template-columns:minmax(0,1fr) 336px;gap:30px}
.pd-gallery{grid-column:1;grid-row:1;min-width:0}
.pd-side{grid-column:2;grid-row:1 / span 2;position:sticky;top:calc(var(--nav-h) + 16px);display:flex;flex-direction:column;gap:14px}
.pd-detail{grid-column:1;grid-row:2;min-width:0}

.pd-media{position:relative;aspect-ratio:16/9;border-radius:16px;overflow:hidden;display:flex;align-items:center;justify-content:center;border:1px solid var(--line)}
.pd-media-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.pd-glyph{width:84px;height:84px;border-radius:22px;background:rgba(255,255,255,.92);color:var(--blue);display:flex;align-items:center;justify-content:center;box-shadow:0 12px 30px rgba(0,0,0,.25)}
/* The two calls to action, under the image rather than over it, sharing the
   width equally so neither reads as the lesser option. */
.pd-cta{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:11px}
.pd-cta:has(>:only-child){grid-template-columns:1fr}
.pd-cta-btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;
  height:48px;padding:0 16px;border-radius:12px;border:1px solid var(--line);background:#fff;
  color:var(--ink);font:inherit;font-size:13.5px;font-weight:700;cursor:pointer;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.pd-cta-btn:hover{border-color:#c9d2ea;background:var(--blue-tint)}
.pd-cta-btn.primary{background:var(--blue);border-color:var(--blue);color:#fff}
.pd-cta-btn.primary:hover{background:var(--blue-deep);border-color:var(--blue-deep)}
.pd-cta-n{font-family:var(--mono);font-size:11px;font-weight:700;color:var(--slate);
  background:var(--blue-tint);border:1px solid var(--line);border-radius:20px;padding:1px 7px}

/* ── Screenshot viewer ── */
.shotv{position:fixed;inset:0;z-index:400;display:flex;align-items:center;justify-content:center;padding:20px}
.shotv-back{position:absolute;inset:0;background:rgba(6,8,20,.82)}
.shotv-panel{position:relative;width:min(1080px,100%);max-height:100%;display:flex;flex-direction:column;
  background:#fff;border-radius:18px;overflow:hidden;box-shadow:var(--shadow-lg)}
.shotv-head{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:15px 18px;border-bottom:1px solid var(--line-soft);flex-shrink:0}
.shotv-head h3{font-size:14.5px;font-weight:800;letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.shotv-head h3 span{display:block;font-size:11.5px;font-weight:600;color:var(--slate);letter-spacing:0}
.shotv-x{width:38px;height:38px;flex-shrink:0;border:1px solid var(--line);border-radius:10px;background:#fff;
  color:var(--slate);display:flex;align-items:center;justify-content:center;cursor:pointer}
.shotv-x:hover{color:var(--ink);border-color:#c9d2ea}
.shotv-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;
  padding:18px;overflow-y:auto}
.shotv-cell{padding:0;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--blue-tint);cursor:pointer}
.shotv-cell:hover{border-color:var(--blue)}
.shotv-cell img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover}

/* One screenshot, filling whatever height is left. */
.shotv-one{position:relative;flex:1;min-height:0;display:flex;align-items:center;justify-content:center;
  background:#0b0b0e;padding:14px}
.shotv-one img{max-width:100%;max-height:100%;object-fit:contain;border-radius:8px}
.shotv-nav{position:absolute;top:50%;transform:translateY(-50%);width:44px;height:44px;border:0;border-radius:50%;
  background:rgba(255,255,255,.9);color:var(--ink);display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:2}
.shotv-nav:hover{background:#fff}
.shotv-nav.prev{left:14px}
.shotv-nav.next{right:14px}
.shotv-bar{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:space-between;
  gap:12px;padding:12px 16px;background:linear-gradient(transparent,rgba(0,0,0,.6));color:#fff;font-size:12px}
.shotv-all{border:0;background:rgba(255,255,255,.16);color:#fff;font:inherit;font-size:12px;font-weight:700;
  padding:7px 13px;border-radius:20px;cursor:pointer}
.shotv-all:hover{background:rgba(255,255,255,.28)}

@media(max-width:600px){
  .shotv{padding:0}
  .shotv-panel{width:100%;height:100%;max-height:100%;border-radius:0}
  .shotv-grid{grid-template-columns:1fr 1fr;gap:9px;padding:12px}
  .shotv-nav{width:38px;height:38px}
  .shotv-nav.prev{left:6px}
  .shotv-nav.next{right:6px}
  .pd-cta-btn{font-size:12.5px;gap:7px;padding:0 10px}
}

/* ── Item form: media ── */
.pf-thumb{display:flex;gap:16px;align-items:flex-start;margin-top:14px;flex-wrap:wrap}
.pf-thumb-box{width:220px;aspect-ratio:16/10;flex-shrink:0;border:1px dashed var(--line);border-radius:12px;
  background:var(--blue-tint);display:flex;align-items:center;justify-content:center;overflow:hidden}
.pf-thumb-box img{width:100%;height:100%;object-fit:cover}
.pf-thumb-empty{font-size:12px;color:var(--slate-light)}
.pf-thumb-side{display:flex;flex-direction:column;gap:9px;align-items:flex-start}
.pf-shots{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:11px;margin:14px 0}
.pf-shots:empty{display:none}
.pf-shot{position:relative;border:1px solid var(--line);border-radius:11px;overflow:hidden;background:var(--blue-tint);cursor:grab}
.pf-shot img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover}
.pf-shot figcaption{position:absolute;left:7px;bottom:7px;font-size:10px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:#fff;background:rgba(11,11,14,.72);border-radius:20px;padding:3px 9px}
.pf-shot-x{position:absolute;top:6px;right:6px;width:24px;height:24px;border:0;border-radius:50%;
  background:rgba(11,11,14,.72);color:#fff;font-size:16px;line-height:1;cursor:pointer;display:flex;
  align-items:center;justify-content:center}
.pf-shot-x:hover{background:#c8352f}
@media(max-width:520px){
  .pf-thumb-box{width:100%}
  .pf-thumb-side{width:100%}
  .pf-shots{grid-template-columns:1fr 1fr}
}

/* ============ Framed live preview ============ */
/* The frame has to fill what is left under the bar, so the chain from html down
   to the iframe all carries a height. */
.html-pv,.pv-body{height:100%}
.pv-body{margin:0;background:var(--black);overflow:hidden}
.pv{display:flex;flex-direction:column;height:100%}
.pv-bar{display:flex;align-items:center;gap:14px;flex-shrink:0;height:60px;padding:0 14px;
  background:var(--black);color:#fff;border-bottom:1px solid rgba(255,255,255,.1)}
.pv-back{width:38px;height:38px;flex-shrink:0;border-radius:50%;border:1px solid rgba(255,255,255,.16);
  background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;color:#fff}
.pv-back:hover{background:rgba(255,255,255,.14)}
.pv-logo{flex-shrink:0;display:flex;align-items:center}
.pv-logo .logo-img{height:26px;width:auto;display:block}
/* The bar carries the way back, the brand and the way to buy. The item's name
   and author are on the page a click away, and repeating them here only ate
   room from the demo. auto margin holds the actions right now that nothing
   between them is doing the pushing. */
.pv-actions{display:flex;align-items:center;gap:10px;flex-shrink:0;margin-left:auto}
.pv-price{font-family:var(--mono);font-size:15px;font-weight:800}
.pv-buy{padding:9px 18px;font-size:13.5px}
.pv-out{width:38px;height:38px;border-radius:10px;border:1px solid rgba(255,255,255,.16);
  background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}
.pv-out:hover{background:rgba(255,255,255,.14)}

.pv-stage{position:relative;flex:1;min-height:0;background:#fff}
.pv-stage iframe{width:100%;height:100%;border:0;display:block}

.pv-loading{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:14px;background:#fff;color:var(--slate);font-size:13px}
.pv-spin{width:30px;height:30px;border:3px solid var(--line);border-top-color:var(--blue);border-radius:50%;
  animation:pv-spin .8s linear infinite}
@keyframes pv-spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){.pv-spin{animation-duration:2.4s}}

/* Sits along the bottom of the frame, so a slow demo is never covered up. */
.pv-hint{position:absolute;left:14px;right:14px;bottom:14px;z-index:3;
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  background:var(--ink);color:#fff;border-radius:12px;padding:12px 14px;
  box-shadow:var(--shadow-lg);font-size:12.5px}
.pv-hint span{flex:1;min-width:180px;color:rgba(255,255,255,.75);line-height:1.55}
.pv-hint a{font-weight:700;color:#8fb0ff;white-space:nowrap}
.pv-hint a:hover{color:#fff;text-decoration:underline}
.pv-hint button{width:28px;height:28px;flex-shrink:0;border:0;border-radius:8px;
  background:rgba(255,255,255,.12);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer}
.pv-hint button:hover{background:rgba(255,255,255,.24)}

@media(max-width:640px){
  .pv-bar{height:54px;gap:10px;padding:0 10px}
  /* The logo stays: putting the demo on our own page is the whole point, and
     with the name gone there is room for it. The price is what goes. */
  .pv-logo .logo-img{height:22px}
  .pv-price{display:none}
  .pv-buy{padding:8px 14px;font-size:12.5px}
  .pv-back,.pv-out{width:34px;height:34px}
}

/* ============ Google sign-in ============ */
/* Always on screen, so the option is visible whether or not the server has a
   client id yet. Our own button is drawn first and Google's replaces it once
   their script loads; unconfigured, a click says so rather than doing nothing. */
.gsi{display:none;margin-bottom:18px}
.gsi.has-google{display:block}
/* The auth modal hides this on the steps where Google means nothing, such as
   the password reset. .gsi.has-google already carries a display, and the UA
   rule for [hidden] is weaker than a two-class selector, so it needs saying at
   the same weight or the block stays on screen. Declared after, so it wins. */
.gsi[hidden]{display:none}
.gsi-btn{display:flex;justify-content:center;min-height:44px}
/* Matched to Google's own button so the swap is not a visible jump. */
.gsi-fallback{display:inline-flex;align-items:center;justify-content:center;gap:10px;
  width:100%;max-width:400px;height:44px;padding:0 20px;border-radius:30px;
  border:1px solid #dadce0;background:#fff;color:#3c4043;cursor:pointer;
  font-family:"Roboto",var(--sans);font-size:14px;font-weight:600;letter-spacing:.2px}
.gsi-fallback:hover{background:#f8faff;border-color:#d2e3fc;box-shadow:0 1px 3px rgba(60,64,67,.15)}
.gsi-fallback svg{flex-shrink:0}
.gsi-btn.is-busy{opacity:.55;pointer-events:none}
/* A rule with the word sitting on it, rather than a line and a floating label. */
.gsi-or{display:flex;align-items:center;gap:12px;margin-top:16px;
  font-size:11.5px;font-weight:600;color:var(--slate-light)}
.gsi-or::before,.gsi-or::after{content:"";flex:1;height:1px;background:var(--line)}
.authm-form+.gsi,.gsi+.authm-form{margin-top:0}

/* ============ Seller level badge ============ */
/* Tone keyed off the level, so renaming one in the admin never restyles it. The
   step classes are the fallback for a rung the stylesheet has not met yet, which
   keeps a newly added level from rendering unstyled. */
.lvl{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;
  letter-spacing:.01em;border-radius:20px;padding:3px 10px 3px 8px;white-space:nowrap;
  border:1px solid transparent;line-height:1.5}
.lvl svg{flex-shrink:0;opacity:.9}

.lvl-s1,.lvl-newcomer{background:#f1f2f6;color:#5c5f6b;border-color:#e2e4ec}
.lvl-s2,.lvl-rising{background:var(--green-wash);color:#0a7048;border-color:#bfe6d5}
.lvl-s3,.lvl-established{background:var(--blue-wash);color:var(--blue-deep);border-color:#cfdcff}
.lvl-s4,.lvl-expert{background:#f3ecfe;color:#6d28d9;border-color:#e0d2fb}
/* The top rung is the only one on a dark ground, so it reads as the end of the
   ladder rather than just another colour. */
.lvl-s5,.lvl-signature{background:linear-gradient(135deg,#0b0b0e,#2a2250);color:#fff;border-color:#3a3266}
.lvl-s5 svg,.lvl-signature svg{color:#f5a524;opacity:1}

/* The seller's own standing, on their dashboard. */
.lvl-panel{background:#fff;border:1px solid var(--line);border-radius:16px;padding:18px 20px;margin-bottom:18px}
.lvl-panel-top{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;flex-wrap:wrap}
.lvl-panel-l{font-size:11px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--slate-light);margin-bottom:8px}
.lvl-panel-rate{text-align:right}
.lvl-panel-rate b{display:block;font-family:var(--mono);font-size:26px;font-weight:800;letter-spacing:-.02em;color:#0a7048}
.lvl-panel-rate span{font-size:11.5px;color:var(--slate)}
.lvl-panel-next{margin-top:16px}
.lvl-bar{height:7px;border-radius:20px;background:var(--blue-tint);border:1px solid var(--line-soft);overflow:hidden}
.lvl-bar span{display:block;height:100%;width:0;border-radius:20px;
  background:linear-gradient(90deg,var(--blue),#5b8bff);transition:width .5s ease}
.lvl-panel-next p{font-size:12.5px;color:var(--slate);margin-top:9px;line-height:1.6}
.lvl-panel-next b{color:var(--ink)}
.lvl-panel-top-note,.lvl-panel-pinned{font-size:12.5px;color:var(--slate);margin-top:14px;line-height:1.6}
@media(max-width:560px){
  .lvl-panel-rate{text-align:left}
  .lvl-panel-rate b{font-size:22px}
}

/* On the item page the badge sits under the store name, where the flat
   "Author" line used to be. */
.pd-author-id{min-width:0;display:flex;flex-direction:column;gap:4px;align-items:flex-start}

/* ── Already owned: overview and support renewal ── */
.pd-own{background:#fff;border:1px solid var(--line);border-radius:16px;overflow:hidden;margin-bottom:16px}
.pd-own-tabs{display:grid;grid-template-columns:1fr 1fr;border-bottom:1px solid var(--line)}
.pd-own-tab{padding:15px 10px;border:0;border-bottom:3px solid transparent;background:none;
  font:inherit;font-size:13.5px;font-weight:700;color:var(--slate);cursor:pointer;margin-bottom:-1px}
.pd-own-tab:hover{color:var(--ink)}
.pd-own-tab.on{color:var(--blue);border-bottom-color:var(--blue)}
.pd-own-sec{padding:18px}
.pd-own-sec h3{font-size:13.5px;font-weight:800;margin-bottom:9px}
.pd-own-sec p{font-size:13px;color:var(--slate);line-height:1.75}
.pd-own-sec a{color:var(--blue);font-weight:600}
.pd-own-sec a:hover{text-decoration:underline}

/* The support block carries its own ground, so its state reads before the words
   are. Green while covered, amber once it has lapsed. */
.pd-own-support{padding:18px;background:var(--green-wash);border-top:1px solid #d6efe4}
.pd-own-support.is-expired{background:#fdf6e7;border-top-color:#f2e3b4}
.pd-own-support-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:9px}
.pd-own-support-head h3{font-size:13.5px;font-weight:800}
.pd-own-support-head span{font-size:12.5px;font-weight:700;color:var(--slate)}
.is-expired .pd-own-support-head span{color:#8a6b06}
.pd-own-support-body{display:flex;align-items:flex-start;justify-content:space-between;gap:14px}
.pd-own-support-body p{font-size:12.5px;color:var(--slate);line-height:1.7;flex:1;min-width:0}
.pd-own-price{flex-shrink:0;font-family:var(--mono);font-size:23px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.pd-own-price .cur{font-size:13px;vertical-align:9px;font-weight:700;color:var(--slate)}
.pd-own-renew{width:100%;justify-content:center;margin-top:14px}
.pd-own-help{display:inline-block;margin-top:12px;font-size:12.5px;font-weight:600;color:var(--blue)}
.pd-own-help:hover{text-decoration:underline}

/* Purchase panel */
.pd-buy{background:#fff;border:1px solid var(--line);border-radius:16px;padding:18px;box-shadow:0 10px 34px rgba(10,17,48,.07)}
.pd-lic{display:flex;flex-direction:column}
.pd-lic-row{position:relative;display:flex;align-items:center;gap:10px;padding:11px 12px;border:1px solid var(--line);border-radius:11px;cursor:pointer;margin-bottom:8px}
.pd-lic-row:hover{border-color:#c2cff0}
.pd-lic-row.on{border-color:var(--blue);background:var(--blue-tint)}
.pd-lic-row input{position:absolute;opacity:0;pointer-events:none}
.pd-lic-dot{width:17px;height:17px;border-radius:50%;border:1.5px solid var(--line);flex-shrink:0;background:#fff}
.pd-lic-row.on .pd-lic-dot{border-color:var(--blue);border-width:5px}
.pd-lic-name{flex:1;font-size:13.5px;font-weight:600}
.pd-lic-price{font-family:var(--mono);font-weight:800;font-size:16px}
.pd-lic-price .free{color:var(--green)}
.pd-lic-grants{list-style:none;margin:0 0 10px;padding:2px 4px 8px;display:flex;flex-direction:column;gap:7px}
.pd-lic-grants li{display:flex;align-items:flex-start;gap:8px;font-size:12.5px;color:var(--ink-soft);line-height:1.45}
.pd-lic-grants svg{color:var(--green);flex-shrink:0;margin-top:2px}
/* Paid support extension, offered as an add-on beside the licence choice. */
.pd-ext{display:flex;align-items:flex-start;gap:10px;padding:12px;border:1px solid var(--line);border-radius:11px;cursor:pointer;margin-bottom:2px}
.pd-ext:hover{border-color:#c2cff0}
.pd-ext:has(input:checked){border-color:var(--blue);background:var(--blue-tint)}
.pd-ext input{position:absolute;opacity:0;pointer-events:none}
.pd-ext-box{width:17px;height:17px;border-radius:5px;border:1.5px solid var(--line);background:#fff;flex-shrink:0;margin-top:1px;position:relative}
.pd-ext:has(input:checked) .pd-ext-box{background:var(--blue);border-color:var(--blue)}
.pd-ext:has(input:checked) .pd-ext-box::after{content:"";position:absolute;left:5px;top:1px;width:4px;height:9px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
.pd-ext-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.pd-ext-t{font-size:13px;font-weight:600;line-height:1.35}
.pd-ext-s{font-size:11.5px;color:var(--slate);line-height:1.4}
.pd-ext-p{font-family:var(--mono);font-weight:700;font-size:13.5px;flex-shrink:0}
/* Tags in the attributes panel, each one a search */
.pd-attr.tags{align-items:flex-start}
.pd-tags{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}
.pd-tags a{font-size:11.5px;font-weight:500;color:var(--blue);background:var(--blue-wash);padding:3px 9px;border-radius:20px;white-space:nowrap}
.pd-tags a:hover{background:var(--blue);color:#fff}
.pd-qty{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:12px 0;border-top:1px solid var(--line-soft)}
.pd-qty label{font-size:13px;font-weight:600}
.qty{display:inline-flex;align-items:center;border:1px solid var(--line);border-radius:9px;overflow:hidden;margin-left:auto}
.qty-btn{width:32px;height:34px;border:0;background:#fff;color:var(--ink-soft);font-size:16px;cursor:pointer;line-height:1}
.qty-btn:hover{background:var(--blue-tint);color:var(--blue)}
.qty-in{width:44px;height:34px;border:0;border-left:1px solid var(--line);border-right:1px solid var(--line);text-align:center;font:inherit;font-size:14px;font-weight:700;-moz-appearance:textfield}
.qty-in::-webkit-outer-spin-button,.qty-in::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.qty-in:focus{outline:none;background:var(--blue-tint)}
.pd-qty-hint{font-size:11.5px;color:var(--slate-light);width:100%}
.pd-total{display:flex;align-items:baseline;justify-content:space-between;padding:12px 0;border-top:1px solid var(--line-soft);font-size:13.5px;color:var(--slate)}
.pd-total-n{font-family:var(--mono);font-size:26px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.pd-add{width:100%;justify-content:center;padding:13px;font-size:15px}
.pd-assure{display:flex;flex-direction:column;gap:9px;margin-top:15px;padding-top:14px;border-top:1px solid var(--line-soft)}
.pd-assure div{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--slate);font-weight:600}
.pd-assure svg{color:var(--blue);flex-shrink:0}

/* Author + attributes */
/* ── The seller card ── */
.pd-author{background:#fff;border:1px solid var(--line);border-radius:16px;padding:16px;
  display:flex;flex-direction:column;gap:14px}
.pd-author-top{display:flex;align-items:center;gap:12px}
/* Round, not a rounded square: this is a person, and every other avatar on the
   site that stands for a person is round too. */
.pd-author .av{width:52px;height:52px;border-radius:50%;overflow:hidden;flex-shrink:0;
  background:linear-gradient(135deg,var(--blue),#7aa0ff);color:#fff;display:flex;
  align-items:center;justify-content:center;font-weight:800;font-size:16px;
  box-shadow:0 0 0 3px #fff,0 0 0 4px var(--line)}
.pd-author .av img{width:100%;height:100%;object-fit:cover;display:block}
.pd-author-id{min-width:0;flex:1}
.pd-author .vn{display:block;font-weight:800;font-size:16px;letter-spacing:-.01em;color:var(--ink);
  text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pd-author .vn:hover{color:var(--blue)}
.pd-author .vl{font-size:13px;color:var(--slate);margin-top:2px}

/* Follow. Outlined until you follow, filled after, so the state is legible
   without reading the label, which at this size there is no room for. */
.pd-follow{display:flex;align-items:center;justify-content:center;width:38px;height:38px;
  flex-shrink:0;border-radius:11px;border:1px solid var(--line);background:#fff;color:var(--slate);
  cursor:pointer;transition:border-color .14s,color .14s,background .14s}
.pd-follow:hover{border-color:var(--blue);color:var(--blue);background:var(--blue-wash)}
.pd-follow .ic-on{display:none}
.pd-follow.is-on{background:var(--blue);border-color:var(--blue);color:#fff}
.pd-follow.is-on:hover{background:var(--blue-deep);border-color:var(--blue-deep)}
.pd-follow.is-on .ic-add{display:none}
.pd-follow.is-on .ic-on{display:block}
.pd-follow:disabled{opacity:.55;cursor:default}

.pd-portfolio{display:flex;align-items:center;justify-content:center;gap:9px;width:100%;
  padding:12px 16px;border:1px solid var(--line);border-radius:11px;background:#fff;
  font-size:14px;font-weight:700;color:var(--ink);text-decoration:none;
  transition:border-color .14s,color .14s,background .14s}
.pd-portfolio:hover{border-color:var(--blue);color:var(--blue);background:var(--blue-tint)}
.pd-portfolio svg{flex-shrink:0}
.pd-attrs{background:#fff;border:1px solid var(--line);border-radius:16px;padding:6px 16px}
.pd-attr{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:11px 0;border-bottom:1px solid var(--line-soft);font-size:12.5px}
.pd-attr:last-child{border-bottom:none}
.pd-attr span{color:var(--slate)}
.pd-attr b{font-weight:600;color:var(--ink);text-align:right}
.pd-attr a{color:var(--blue)}

/* Tabs */
.pd-tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom:22px;overflow-x:auto;scrollbar-width:none}
.pd-tabs::-webkit-scrollbar{display:none}
.pd-tab{display:inline-flex;align-items:center;gap:7px;padding:12px 16px;font-size:14px;font-weight:700;color:var(--slate);
  background:none;border:0;border-bottom:2px solid transparent;margin-bottom:-1px;cursor:pointer;white-space:nowrap}
.pd-tab:hover{color:var(--blue)}
.pd-tab.on{color:var(--blue);border-bottom-color:var(--blue)}
.pd-tab-n{font-family:var(--mono);font-size:11px;background:var(--blue-wash);color:var(--blue);padding:2px 7px;border-radius:20px}
.pd-desc{color:var(--ink-soft);font-size:15px;line-height:1.75}
.pd-desc p{margin-bottom:13px}
.pd-desc p:last-child{margin-bottom:0}

.pd-rating{display:flex;gap:26px;align-items:center;background:var(--blue-tint);border:1px solid var(--line-soft);border-radius:16px;padding:22px;flex-wrap:wrap}
.pd-rating-big{text-align:center;flex-shrink:0}
.pd-rating-big .rn{font-size:42px;font-weight:800;line-height:1}
.pd-rating-big .rstars{color:var(--amber);font-size:15px;margin:6px 0 2px}
.pd-rating-big .rc{font-size:12px;color:var(--slate)}
.pd-rating-note{color:var(--slate);font-size:14px;line-height:1.6;flex:1;min-width:180px}

/* Comments */
.cm-intro{font-size:14px;color:var(--slate);line-height:1.6;margin-bottom:16px}
.cm-write{background:#fff;border:1px solid var(--line);border-radius:14px;padding:16px;margin-bottom:20px}
.cm-write textarea{resize:vertical;min-height:76px}
.cm-write-actions{display:flex;gap:9px;margin-top:11px;flex-wrap:wrap}
.btn-sm{padding:8px 15px;font-size:13px}
/* Quantity in the licence dialog: it applies to whichever licence is picked,
   so it sits in the footer with the button rather than on one of the cards. */
.tierm-qty{display:flex;align-items:center;gap:10px;margin-right:auto}
.tierm-qty label{font-size:12.5px;font-weight:600;color:var(--slate)}
@media(max-width:600px){
  .tierm-foot{flex-wrap:wrap;gap:10px}
  .tierm-qty{margin-right:0;width:100%;justify-content:space-between}
  .tierm-foot .btn-primary{width:100%;justify-content:center;order:3}
  .tierm-details{order:2}
}
/* Comments are a public Q&A with the author, not a flat stream, so each thread
   is one card and the author's answer is the thing the eye should land on.
   Previously threads were divided by a hairline only, replies were marked by a
   2px rule that all but vanished on a phone, and .by-author was emitted by the
   JS with no style behind it, so the answer people came to read looked exactly
   like every other line. */
/* One bordered container of hairline-separated rows, not a stack of cards.
   Cards gave every comment its own padding, radius, shadow and gap, which is
   what made each one read as a big block. Flat rows put the words first. */
.cm-list{border:1px solid var(--line);border-radius:8px;overflow:hidden;background:#fff}
.cm-thread{display:block}
.cm-thread + .cm-thread{border-top:1px solid var(--line)}

.cm-item{display:flex;gap:12px;padding:13px 15px;background:var(--blue-tint)}
.cm-item + .cm-item{border-top:1px solid var(--line-soft)}
/* Replies step in and sit on white, so the question that opened the thread is
   the tinted one and the answers under it read as subordinate. */
.cm-item.reply{background:#fff;padding-left:32px}

/* Square, like the reference. A circle plus a pill badge plus a rounded card
   was three different rounded shapes competing inside 40px. */
.cm-av{width:40px;height:40px;border-radius:3px;flex-shrink:0;display:flex;align-items:center;justify-content:center;
  font-weight:800;font-size:15px;background:#c9ccd6;color:#fff}
.cm-av.au{background:var(--blue);color:#fff}
.cm-main{flex:1;min-width:0}

/* Name and badge left, time hard right, as in the reference. */
.cm-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.cm-name{font-weight:700;font-size:13.5px;color:var(--blue)}
.cm-badge{font-size:9.5px;font-weight:700;padding:2px 6px;border-radius:2px;text-transform:uppercase;
  letter-spacing:.03em;line-height:1.35}
.cm-badge.author{background:#8a8d99;color:#fff}
.cm-badge.buyer{background:var(--ink);color:#fff}
.cm-when{font-size:11.5px;color:var(--slate-light);margin-left:auto}
.cm-body{font-size:13.5px;line-height:1.6;color:var(--ink-soft);margin-top:5px;white-space:pre-wrap;word-break:break-word}

.cm-reply-btn{margin-top:7px;background:none;border:0;padding:0;font-size:12.5px;font-weight:600;
  color:var(--slate);cursor:pointer}
.cm-reply-btn:hover{color:var(--blue);text-decoration:underline}
.cm-reply-btn:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.cm-reply-box{margin-top:12px}
.cm-reply-box textarea{resize:vertical}
/* ── Product detail: features, specs, docs, changelog ────────
   Every one of these renders only when the seller filled it in, so an older
   item simply shows what it always showed. */
.pd-features{list-style:none;padding:0;margin:0 0 22px;display:grid;gap:9px}
.pd-features li{position:relative;padding-left:26px;font-size:14.5px;line-height:1.55;color:var(--ink-soft)}
.pd-features li::before{content:"";position:absolute;left:4px;top:.5em;width:7px;height:7px;border-radius:50%;
  background:var(--blue)}

/* Requirements and the file list, now in the sidebar card rather than the
   bottom of the description. They keep the row rhythm of the .pd-attr lines
   above them and open on demand, so the card gains two lines instead of two
   sections. */
.pd-spec-fold{border-bottom:1px solid var(--line-soft);font-size:12.5px}
.pd-spec-fold:last-of-type{border-bottom:none}
.pd-spec-fold > summary{display:flex;align-items:center;gap:6px;padding:11px 0;
  cursor:pointer;list-style:none;color:var(--slate);user-select:none}
.pd-spec-fold > summary::-webkit-details-marker{display:none}
/* The disclosure arrow, drawn rather than relying on the default marker so it
   sits on the right and turns with the state. */
.pd-spec-fold > summary::after{content:"";margin-left:auto;width:7px;height:7px;
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .18s ease}
.pd-spec-fold[open] > summary::after{transform:rotate(225deg) translate(-1px,-1px)}
.pd-spec-fold > summary:hover{color:var(--ink)}
.pd-spec-fold > summary:focus-visible{outline:2px solid var(--blue);outline-offset:2px;border-radius:4px}
.pd-spec-n{font-size:11px;font-weight:700;color:var(--ink-soft);background:var(--blue-tint);
  border-radius:20px;padding:1px 7px}
.pd-spec-fold > :not(summary){padding-bottom:12px}

/* Label and value on one row, so the list reads as a spec sheet. Narrow
   column, so the label is capped tighter than it was in the wide one. */
.spec-dl{margin:0;display:flex;flex-direction:column;gap:7px}
.spec-dl > div{display:flex;gap:10px;font-size:12px;line-height:1.45}
.spec-dl dt{flex:0 0 42%;max-width:104px;font-weight:700;color:var(--ink);margin:0;word-break:break-word}
.spec-dl dd{flex:1;min-width:0;margin:0;color:var(--slate);word-break:break-word;text-align:right}
.spec-files{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:5px}
.spec-files li{font-size:11.5px;font-weight:600;color:var(--ink-soft);background:var(--blue-tint);
  border:1px solid var(--line);border-radius:20px;padding:3px 9px}

.pd-docs{display:inline-flex;align-items:center;gap:7px;margin-top:22px;font-size:13.5px;font-weight:700;
  color:var(--blue);text-decoration:none}
.pd-docs:hover{text-decoration:underline}
.pd-docs svg{flex-shrink:0}

.chg-log{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:0}
.chg-log li{padding:16px 0;border-bottom:1px solid var(--line-soft)}
.chg-log li:first-child{padding-top:0}
.chg-log li:last-child{border-bottom:none}
.chg-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:7px}
.chg-v{font-size:12.5px;font-weight:800;color:var(--blue);background:var(--blue-wash);
  border-radius:5px;padding:3px 9px}
.chg-d{font-size:12px;color:var(--slate-light)}
.chg-b{font-size:13.5px;line-height:1.65;color:var(--ink-soft);margin:0;white-space:pre-wrap;word-break:break-word}

/* ── Category tree ───────────────────────────────────────────
   A bordered, scrolling list with children indented under their parent, so the
   structure is visible while choosing. This replaced a category dropdown plus
   a second dropdown that only appeared once the first was answered, which hid
   the hierarchy entirely. */
/* Tinted rather than outlined. It sits inside a panel that is already a bordered
   box, so its own border drew a second rectangle 14px inside the first. The tint
   still marks it as a region that scrolls, without the double frame. */
.cat-tree{border:0;border-radius:10px;background:var(--blue-tint);
  max-height:260px;overflow-y:auto;padding:6px;scrollbar-width:thin}
.cat-tree::-webkit-scrollbar{width:9px}
.cat-tree::-webkit-scrollbar-thumb{background:#d3d9ea;border-radius:20px;border:2px solid var(--blue-tint)}
.cat-tree-loading{font-size:12.5px;color:var(--slate-light);margin:0;padding:8px}
.cat-row{display:flex;align-items:center;gap:9px;padding:6px 8px;border-radius:7px;
  font-size:13px;color:var(--black);cursor:pointer}
/* White on the tinted tree, not tint on white: the tree carries the tint now, so
   a tinted hover would have been the row painting itself its own background. */
.cat-row:hover{background:#fff}
/* Indented, and a shade lighter, so a child reads as belonging to the row
   above it without needing a connector line in a list this small. */
.cat-row.is-child{padding-left:30px;font-size:12.5px;color:var(--ink-soft)}
.cat-row input{width:15px;height:15px;flex-shrink:0;accent-color:var(--blue);cursor:pointer;margin:0}
.cat-row:has(input:checked){background:#fff;box-shadow:inset 0 0 0 1px #c6d2ff}
.cat-row:has(input:checked) span{font-weight:700;color:var(--blue)}
.cat-row input:focus-visible{outline:2px solid var(--blue);outline-offset:2px}

/* The package card while the item is still unsaved, and the nudge once it is
   saved but has no file yet. */
.pf-locked{color:var(--slate-light);line-height:1.55}
.pf-missing{color:#b42318;line-height:1.55;margin-top:10px}

/* ── Product form: repeating rows ────────────────────────── */
.req-list,.chg-list{display:flex;flex-direction:column;gap:10px;margin-bottom:12px}
.req-row{display:flex;gap:9px;align-items:center}
.req-row .auth-input:first-child{flex:0 0 34%}
.req-row .auth-input:nth-child(2){flex:1;min-width:0}
.chg-row{border:1px solid var(--line);border-radius:12px;padding:12px;background:#fff}
.chg-row-top{display:flex;gap:9px;align-items:center;margin-bottom:9px}
.chg-row-top .auth-input:first-child{flex:0 0 30%}
.chg-row-top .auth-input:nth-child(2){flex:1;min-width:0}
/* A plain remove control that keeps a real tap target without looking like a
   second action competing with Save. */
.icon-x{flex-shrink:0;width:34px;height:34px;border-radius:9px;border:1px solid var(--line);
  background:#fff;color:var(--slate-light);font-size:19px;line-height:1;cursor:pointer;
  display:flex;align-items:center;justify-content:center;transition:color .15s,border-color .15s}
.icon-x:hover{color:#b42318;border-color:#f3d0cc}
.chk-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:9px;margin-bottom:14px}
.chk{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--ink-soft);cursor:pointer}
.chk input{width:16px;height:16px;flex-shrink:0;accent-color:var(--blue);cursor:pointer}

@media(max-width:600px){
  /* Label over value: side by side left about eight characters for each. */
  .req-row{flex-wrap:wrap}
  .req-row .auth-input:first-child,.req-row .auth-input:nth-child(2){flex:1 1 100%}
  .req-row .icon-x{margin-left:auto}
  .chg-row-top{flex-wrap:wrap}
  .chg-row-top .auth-input:first-child,.chg-row-top .auth-input:nth-child(2){flex:1 1 calc(50% - 22px)}
  /* Stacked on a narrow screen, so the value returns to the left edge under
     its label rather than staying flush right where it would look detached. */
  .spec-dl > div{flex-direction:column;gap:2px}
  .spec-dl dt{flex:none;max-width:none}
  .spec-dl dd{text-align:left}
}

.pd-related{margin-top:56px}

@media(max-width:900px){
  .pd-grid{grid-template-columns:1fr;gap:24px}
  .pd-gallery,.pd-side,.pd-detail{grid-column:1;grid-row:auto}
  .pd-side{position:static}
  .pd-hero{padding-bottom:16px;margin-bottom:18px}
  .pd-media{aspect-ratio:16/10;border-radius:14px}
  .pd-rating{gap:18px;padding:18px}
  .pd-rating-big .rn{font-size:34px}
}
@media(max-width:520px){
  .pd-meta{gap:8px 14px;font-size:12.5px}
  .pd-thumb{width:62px;height:44px}
  .pd-buy{padding:15px;border-radius:14px}
  .pd-tab{padding:11px 12px;font-size:13px}
  /* The connector shifts in with the smaller avatar rather than collapsing to
     an indent, so a reply still reads as a reply on the narrowest phone. */
  .cm-item{gap:10px;padding:11px 12px}
  .cm-item.reply{padding-left:24px}
  .cm-av{width:34px;height:34px;font-size:13px}
  /* Wraps under the name rather than squeezing it, which on a narrow phone
     left about four characters for a username. */
  .cm-when{margin-left:0;width:100%}
  .pd-live{bottom:12px;padding:9px 16px;font-size:12.5px}
}


/* ---- Vendor storefront ---- */
.vend{padding:8px 0 60px}

/* ── The profile header, as one card ──────────────────────────
   Cover, then the identity block under it with the avatar straddling the join,
   then the counts as the card's own footer. One object, so "who this is" reads
   as one thing rather than three stacked panels. */
.vend-card{background:#fff;border:1px solid var(--line);border-radius:18px;overflow:hidden;
  margin:8px 0 26px;box-shadow:var(--shadow)}
.vend-cover{height:190px;background:var(--blue-tint);position:relative}
.vend-cover img{width:100%;height:100%;object-fit:cover;display:block}
/* No cover uploaded. A flat tint reads as an image that failed, so the empty
   state is a deliberate pattern in the brand's own colours. */
.vend-cover-art{position:absolute;inset:0;
  background:
    radial-gradient(circle at 18% 130%,rgba(31,82,255,.30),transparent 46%),
    radial-gradient(circle at 82% -20%,rgba(16,185,129,.24),transparent 44%),
    repeating-linear-gradient(115deg,rgba(255,255,255,.5) 0 2px,transparent 2px 22px),
    linear-gradient(120deg,#0d1330,#1d2a63 55%,#12306b)}

.vend-id{display:flex;align-items:flex-start;gap:20px;padding:0 26px 20px;position:relative}
/* Pulled up over the cover, with a white ring so it reads as sitting on top of
   the photo rather than being cut out of it. */
.av.lg{width:112px;height:112px;border-radius:50%;overflow:hidden;flex-shrink:0;margin-top:-52px;
  background:linear-gradient(135deg,var(--blue),#7aa0ff);color:#fff;display:flex;
  align-items:center;justify-content:center;font-weight:800;font-size:36px;
  box-shadow:0 0 0 5px #fff,0 6px 18px rgba(10,17,48,.18)}
.av.lg img{width:100%;height:100%;object-fit:cover;display:block}
.vend-id-main{flex:1;min-width:0;padding-top:14px}
.vend-id h1{font-size:27px;font-weight:800;letter-spacing:-.025em;line-height:1.2;margin:0}

.vend-line{display:flex;align-items:center;flex-wrap:wrap;gap:10px;margin-top:9px}
.vend-lvl{font-size:13px;font-weight:700;color:var(--blue);background:var(--blue-wash);
  border-radius:20px;padding:4px 12px}
.vend-meta{font-size:13.5px;color:var(--slate);margin:10px 0 0}
.vend-bio{font-size:14.5px;line-height:1.65;color:var(--ink-soft);margin:11px 0 0;max-width:70ch}

.vend-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}
.vend-actions .btn{padding:10px 18px;font-size:14px}
.vend-follow .ic-on{display:none}
.vend-follow.is-on{background:var(--blue);border-color:var(--blue);color:#fff}
.vend-follow.is-on:hover{background:var(--blue-deep);border-color:var(--blue-deep);color:#fff}
.vend-follow.is-on .ic-add{display:none}
.vend-follow.is-on .ic-on{display:block}

.vend-score{flex-shrink:0;padding-top:16px;text-align:right}
.vend-stars{display:flex;align-items:center;gap:2px;justify-content:flex-end}
.vend-stars svg{color:var(--line)}
.vend-stars svg.on{color:var(--amber)}
.vend-stars span{font-size:13px;color:var(--slate);margin-left:7px;white-space:nowrap}
.vend-stars.none{font-size:13px;color:var(--slate-light)}

/* Counts, not tabs to pages that do not exist. Only the one that leads
   somewhere is a link, and it says so by being one. */
.vend-tabs{display:flex;flex-wrap:wrap;gap:0;border-top:1px solid var(--line);background:var(--blue-tint)}
.vend-tab{display:flex;align-items:baseline;gap:6px;padding:13px 22px;font-size:13.5px;
  color:var(--slate);text-decoration:none;border-right:1px solid var(--line)}
.vend-tab b{font-size:16px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums}
/* Items and Sales are buttons now, since they switch a pane rather than
   navigate. A button brings its own background, border and font, so those are
   reset back to the shared tab look. */
button.vend-tab{background:none;border:0;border-right:1px solid var(--line);font:inherit;font-size:13.5px;cursor:pointer;color:var(--slate)}
button.vend-tab:hover{background:#fff;color:var(--blue)}
button.vend-tab:hover b{color:var(--blue)}
.vend-tab.is-on{background:#fff}
button.vend-tab.is-on b{color:var(--blue)}

/* The sold count under a card in the Sales view. Sits with the card rather
   than inside it, so the card partial stays the one shared thing it is. */
.vend-sold-wrap{display:flex;flex-direction:column;gap:8px}
.vend-sold{display:flex;align-items:baseline;justify-content:center;gap:5px;padding:7px 10px;
  border:1px solid var(--line);border-radius:10px;background:var(--blue-tint)}
.vend-sold b{font-size:15px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums}
.vend-sold span{font-size:12px;color:var(--slate)}

/* ── Body: portfolio beside a rail ── */
.vend-body{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:26px;align-items:start}
.vend-main{min-width:0}
.vend-side{position:sticky;top:calc(var(--nav-h) + 16px);display:flex;flex-direction:column;gap:14px}
.vend-box{background:#fff;border:1px solid var(--line);border-radius:14px;padding:18px}
.vend-box h2{font-size:15px;font-weight:800;letter-spacing:-.01em;margin:0 0 13px}
.vend-box-note{font-size:11.5px;line-height:1.6;color:var(--slate-light);margin:13px 0 0}

.vend-feat{display:flex;flex-direction:column}
.vend-feat-row{display:flex;align-items:center;gap:11px;padding:9px 0;text-decoration:none;
  border-bottom:1px solid var(--line-soft)}
.vend-feat-row:last-child{border-bottom:0;padding-bottom:0}
.vend-feat-th{width:46px;height:34px;border-radius:7px;overflow:hidden;flex-shrink:0;
  background:var(--blue-tint);color:var(--blue);display:flex;align-items:center;justify-content:center}
.vend-feat-th img{width:100%;height:100%;object-fit:cover;display:block}
.vend-feat-t{min-width:0;display:flex;flex-direction:column;gap:2px}
.vend-feat-t .n{font-size:12.5px;font-weight:600;color:var(--ink);line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.vend-feat-row:hover .n{color:var(--blue)}
.vend-feat-t .p{font-size:12px;font-weight:700;color:var(--slate)}

.vend-ask{text-align:center}
.vend-ask p{font-size:13px;line-height:1.6;color:var(--slate);margin:0 0 14px}
.vend-ask .btn{width:100%;justify-content:center}

/* Store settings: where Contact author points. */
.set-contact{margin-top:6px;padding-top:20px;border-top:1px solid var(--line-soft)}
.set-contact-head strong{display:block;font-size:14px;color:var(--ink);margin-bottom:5px}
.set-contact-head p{font-size:12.5px;line-height:1.6;color:var(--slate);margin:0 0 16px}
/* The channel picker sits beside its value, and stacks on a narrow screen. */
.set-contact-row{display:grid;grid-template-columns:170px 1fr;gap:14px 16px;align-items:start}
@media (max-width:640px){.set-contact-row{grid-template-columns:1fr}}

@media(max-width:980px){
  .vend-body{grid-template-columns:1fr}
  .vend-side{position:static}
}
@media(max-width:760px){
  /* The avatar stops straddling the cover and the header stacks: at this width
     a 112px circle beside the name leaves the name nowhere to go. */
  .vend-cover{height:130px}
  .vend-id{flex-direction:column;align-items:flex-start;gap:0;padding:0 18px 18px}
  .av.lg{width:82px;height:82px;font-size:28px;margin-top:-38px}
  .vend-id-main{padding-top:12px;width:100%}
  .vend-id h1{font-size:22px}
  .vend-score{padding-top:12px;text-align:left;width:100%}
  .vend-stars{justify-content:flex-start;margin-top:10px}
  .vend-actions .btn{flex:1 1 auto;justify-content:center}
  .vend-tab{padding:11px 15px;font-size:12.5px}
  .vend-tab b{font-size:14.5px}
}
@media(max-width:520px){
  /* Edge to edge, the same as the cart and the checkout. A cover photo is the
     one thing on this site that most wants the full width, and 24px of page
     padding either side of it on a 360px phone is 13% of the screen spent on
     nothing. The card squares off against the glass; the parts that are text
     keep their own inset so nothing touches the edge. */
  .vend{padding-top:0}
  .vend .wrap{padding-left:0;padding-right:0}
  .vend-card{border-radius:0;border-left:0;border-right:0;margin-top:0;box-shadow:none}
  .vend-cover{height:104px}
  .av.lg{width:70px;height:70px;font-size:24px;margin-top:-32px;box-shadow:0 0 0 4px #fff,0 6px 18px rgba(10,17,48,.18)}
  .vend-id{padding:0 14px 15px}
  .vend-id h1{font-size:20px}
  .vend-bio{font-size:13.5px}
  .vend-tab{flex:1 1 auto;justify-content:center;padding:10px 8px;border-right:0;
    border-top:1px solid var(--line)}
  /* The grid and the rail are content, not chrome, so they keep a gutter. */
  .vend-main,.vend-side{padding:0 14px}
  .vend-box{padding:15px;border-radius:12px}
}

/* ---- 404 ---- */
.nf{padding:80px 0}
.nf-inner{text-align:center;max-width:460px;margin:0 auto}
.nf-code{font-family:var(--mono);font-size:64px;font-weight:800;color:var(--blue);letter-spacing:-.02em}
.nf-inner h1{font-size:26px;font-weight:800;margin:6px 0 10px}
.nf-inner p{color:var(--slate);margin-bottom:24px}
.nf-actions{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}
/* The removed-item page. A mark instead of the big 404 numeral: this visitor
   followed a real link to a real item, so shouting an error code at them is
   the wrong tone. */
.nf-mark{width:56px;height:56px;margin:0 auto 14px;border-radius:16px;background:var(--blue-tint);border:1px solid var(--line);color:var(--blue);display:flex;align-items:center;justify-content:center}
.nf-inner .nf-sub{font-size:13.5px;line-height:1.65;padding:11px 14px;border-radius:11px;background:var(--blue-tint);border:1px solid var(--line);margin-bottom:24px}

/* ---- Sell ---- */
/* ═══════════════════════════════════════════════════════════
   BECOME A SELLER  (/domzivo/become-a-seller)
   ═══════════════════════════════════════════════════════════ */
/* One dark section at the top and light everything after it. The hero is the
   only place the page raises its voice, and what it raises it about is a
   number, so the number gets its own panel rather than a sentence. */

/* Straight down, and starting on pure black. The navbar above is var(--black),
   so an angled gradient met it with a seam: black on the left of the join,
   navy on the right. Beginning at #000 and turning blue on the way down means
   the header and the hero are one surface with no edge between them. */
.sl-hero{background:linear-gradient(180deg,#000 0%,#05070f 9%,#0c1638 46%,#12276f 100%);
  color:#fff;padding:64px 0 70px;position:relative;overflow:hidden}
/* A faint grid, angled, so the panel has something to sit against without a
   photograph that has to load and can look broken while it does. */
.sl-hero::before{content:"";position:absolute;inset:-40% -10% auto;height:180%;
  background:repeating-linear-gradient(64deg,rgba(255,255,255,.045) 0 1px,transparent 1px 46px);
  pointer-events:none}
.sl-hero>.wrap{position:relative}
.sl-hero-in{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:52px;align-items:center}
.sl-hero-copy{min-width:0}
.sl-hero .hero-badge{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.16);
  color:#fff;box-shadow:none}
.sl-hero .hero-badge .bic{background:rgba(143,176,255,.16);color:#a9c2ff}
.sl-hero h1{font-size:46px;font-weight:800;letter-spacing:-.035em;line-height:1.1;margin:18px 0 16px}
.sl-hero .hl{color:#8fb0ff}
.sl-hero .dot{color:#4a7bff}
.sl-hero-copy>p{color:rgba(255,255,255,.7);font-size:16.5px;line-height:1.65;max-width:56ch;margin:0}

.sl-cta{display:flex;flex-wrap:wrap;gap:11px;margin-top:26px}
.sl-cta .btn{padding:13px 26px;font-size:15px}
.sl-btn-ghost{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.2);color:#fff}
.sl-btn-ghost:hover{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.34);color:#fff}

.sl-assure{display:flex;flex-wrap:wrap;gap:8px 22px;list-style:none;margin:26px 0 0;padding:0}
.sl-assure li{display:flex;align-items:center;gap:7px;font-size:13.5px;color:rgba(255,255,255,.62)}
.sl-assure svg{color:#3ddc9a;flex-shrink:0}

/* The rate panel. Its own object, not a paragraph: a seller scanning this page
   is looking for one number and this is where it lives. */
.sl-rate{background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.13);
  border-radius:18px;padding:26px 24px;backdrop-filter:blur(2px)}
.sl-rate-n{font-size:26px;font-weight:800;color:#8fb0ff;line-height:1;letter-spacing:-.03em}
.sl-rate-n span{font-size:66px;letter-spacing:-.05em;color:#fff}
.sl-rate-l{font-size:14px;color:rgba(255,255,255,.72);margin:10px 0 0;line-height:1.5}
.sl-rate-rule{height:1px;background:rgba(255,255,255,.14);margin:18px 0}
.sl-rate-s{font-size:12.5px;line-height:1.65;color:rgba(255,255,255,.55);margin:0}
.sl-rate-s b{color:#fff;font-weight:700}
.sl-rate-stats{display:flex;gap:26px;margin-top:20px;padding-top:18px;border-top:1px solid rgba(255,255,255,.14)}
.sl-rate-stats b{display:block;font-size:21px;font-weight:800;color:#fff;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums}
.sl-rate-stats span{font-size:11.5px;color:rgba(255,255,255,.5)}

/* ── Sections ── */
.sl-sec{padding:60px 0}
.sl-head{max-width:62ch;margin:0 0 30px}
.sl-head h2{font-size:29px;font-weight:800;letter-spacing:-.028em;line-height:1.2;margin:0 0 10px}
.sl-head p{font-size:15.5px;line-height:1.65;color:var(--slate);margin:0}
.sl-head a{color:var(--blue);font-weight:600}
.sl-head a:hover{text-decoration:underline}

/* ── The calculator ── */
.sl-calc{background:#fff;border:1px solid var(--line);border-radius:18px;overflow:hidden;
  box-shadow:var(--shadow)}
.sl-calc-top{display:flex;align-items:center;flex-wrap:wrap;gap:14px 20px;padding:20px 24px;
  background:var(--blue-tint);border-bottom:1px solid var(--line)}
.sl-calc-top label{font-size:13px;font-weight:700;color:var(--ink)}
.sl-price-in{display:flex;align-items:center;gap:2px;background:#fff;border:1px solid var(--line);
  border-radius:11px;padding:0 14px;transition:border-color .13s,box-shadow .13s}
.sl-price-in:focus-within{border-color:var(--blue);box-shadow:0 0 0 3px rgba(31,82,255,.1)}
.sl-price-in span{font-size:17px;font-weight:700;color:var(--slate-light)}
.sl-price-in input{width:92px;border:0;background:none;outline:none;padding:11px 0;
  font-family:var(--mono);font-size:19px;font-weight:700;color:var(--ink)}
/* The spinners are 20px of chrome that nobody uses and that changes the value
   by one when a seller means to change it by fifty. */
.sl-price-in input::-webkit-outer-spin-button,
.sl-price-in input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.sl-price-in input[type=number]{-moz-appearance:textfield}
.sl-presets{display:flex;flex-wrap:wrap;gap:6px;margin-left:auto}
.sl-preset{font-family:var(--mono);font-size:12.5px;font-weight:700;color:var(--slate);
  background:#fff;border:1px solid var(--line);border-radius:8px;padding:7px 11px;cursor:pointer;
  transition:border-color .13s,color .13s,background .13s}
.sl-preset:hover{border-color:var(--blue);color:var(--blue)}
.sl-preset.is-on{background:var(--blue);border-color:var(--blue);color:#fff}

.sl-ladder{list-style:none;margin:0;padding:0}
.sl-rung{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(90px,1fr) 82px 96px;
  align-items:center;gap:20px;padding:16px 24px;border-bottom:1px solid var(--line-soft)}
.sl-rung:last-child{border-bottom:0}
.sl-rung.is-top{background:linear-gradient(90deg,var(--blue-wash),transparent 70%)}
.sl-rung-id{display:flex;align-items:center;gap:12px;min-width:0}
.sl-rung-dot{width:11px;height:11px;border-radius:50%;flex-shrink:0;
  background:var(--line);box-shadow:0 0 0 3px var(--line-soft)}
.sl-rung.is-start .sl-rung-dot{background:var(--slate-light);box-shadow:0 0 0 3px #e9ebf2}
.sl-rung.is-top .sl-rung-dot{background:var(--blue);box-shadow:0 0 0 3px #ccd8ff}
.sl-rung-id b{display:block;font-size:14.5px;font-weight:700;color:var(--ink);line-height:1.3}
.sl-rung-id em{display:block;font-style:normal;font-size:12px;color:var(--slate-light);margin-top:2px}
.sl-rung-bar{height:7px;border-radius:20px;background:var(--line-soft);overflow:hidden}
.sl-rung-bar span{display:block;height:100%;border-radius:20px;
  background:linear-gradient(90deg,#7aa0ff,var(--blue))}
.sl-rung.is-top .sl-rung-bar span{background:linear-gradient(90deg,var(--blue),var(--blue-deep))}
.sl-rung-keep,.sl-rung-take{text-align:right}
.sl-rung-keep b,.sl-rung-take b{display:block;font-size:16px;font-weight:800;color:var(--ink);
  letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.sl-rung-take b{color:var(--green);font-family:var(--mono);font-size:17px}
.sl-rung-keep em,.sl-rung-take em{display:block;font-style:normal;font-size:11px;
  color:var(--slate-light);margin-top:1px}
.sl-calc-note{font-size:12.5px;line-height:1.65;color:var(--slate-light);margin:0;
  padding:15px 24px;border-top:1px solid var(--line);background:var(--blue-tint)}
.sl-calc-note a{color:var(--blue);font-weight:600}
.sl-calc-note a:hover{text-decoration:underline}

/* ── What is handled ── */
.sl-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.sl-card{background:#fff;border:1px solid var(--line);border-radius:15px;padding:22px}
.sl-ic{display:flex;align-items:center;justify-content:center;width:40px;height:40px;
  border-radius:12px;background:var(--blue-wash);color:var(--blue);margin-bottom:14px}
.sl-ic svg{width:20px;height:20px}
.sl-card h3{font-size:15.5px;font-weight:700;letter-spacing:-.01em;margin:0 0 7px}
.sl-card p{font-size:13.5px;line-height:1.65;color:var(--slate);margin:0}

/* ── Steps ── */
/* A rule runs behind the numbers, so four cards read as a sequence rather than
   as four unrelated boxes that happen to be numbered. */
.sl-steps{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));gap:20px;position:relative}
.sl-steps::before{content:"";position:absolute;top:19px;left:9%;right:9%;height:2px;
  background:repeating-linear-gradient(90deg,var(--line) 0 7px,transparent 7px 14px)}
.sl-steps li{position:relative}
.sl-step-n{display:flex;align-items:center;justify-content:center;width:38px;height:38px;
  border-radius:50%;background:var(--blue);color:#fff;font-family:var(--mono);font-size:14px;
  font-weight:700;margin-bottom:15px;box-shadow:0 0 0 5px #fff}
.sl-steps h3{font-size:15.5px;font-weight:700;margin:0 0 7px}
.sl-steps p{font-size:13.5px;line-height:1.65;color:var(--slate);margin:0}

/* ── Categories ── */
.sl-cats{display:flex;flex-wrap:wrap;gap:9px}
.sl-cat{display:inline-flex;align-items:center;gap:9px;background:#fff;border:1px solid var(--line);
  border-radius:11px;padding:11px 15px;font-size:13.5px;font-weight:600;color:var(--ink);
  text-decoration:none;transition:border-color .13s,color .13s}
.sl-cat:hover{border-color:var(--blue);color:var(--blue)}
.sl-cat svg{color:var(--slate-light);flex-shrink:0}
.sl-cat:hover svg{color:var(--blue)}
.sl-cat span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ── Payouts ── */
.sl-payouts{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:44px;align-items:center}
.sl-pay-copy h2{font-size:29px;font-weight:800;letter-spacing:-.028em;margin:0 0 12px}
.sl-pay-copy p{font-size:15.5px;line-height:1.7;color:var(--slate);margin:0 0 16px;max-width:52ch}
.sl-link{display:inline-flex;align-items:center;gap:7px;font-size:14px;font-weight:700;
  color:var(--blue);text-decoration:none}
.sl-link:hover{text-decoration:underline}
.sl-link svg{transition:transform .16s}
.sl-link:hover svg{transform:translateX(3px)}
.sl-pay-list{display:flex;flex-direction:column;gap:11px}
.sl-pay{display:flex;align-items:center;gap:14px;background:#fff;border:1px solid var(--line);
  border-radius:13px;padding:16px 18px}
.sl-pay-ic{display:flex;align-items:center;justify-content:center;width:42px;height:42px;
  flex-shrink:0;border-radius:12px;background:var(--blue-tint);color:var(--blue)}
.sl-pay-ic svg{width:20px;height:20px}
/* Scoped to the text block, not to every span in the row. `.sl-pay span` also
   matched .sl-pay-ic, which is a span, and at higher specificity than the class
   itself, so it replaced the icon box's display:flex with display:block. The
   centring was being switched off by a rule meant for the caption underneath. */
.sl-pay>div b{display:block;font-size:14.5px;font-weight:700;color:var(--ink)}
.sl-pay>div span{display:block;font-size:12.5px;color:var(--slate);margin-top:2px}

/* ── FAQ ── */
/* The answers keep their reading measure and the scene takes the space that
   measure leaves over, rather than the list being stretched to a width nobody
   can comfortably read. */
.sl-faq-wrap{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:50px;align-items:center}
.sl-faq-art{display:flex;justify-content:center}
.sl-faq-art img{width:100%;max-width:280px;height:auto;display:block}
.sl-faq{display:flex;flex-direction:column;gap:10px;min-width:0}
.sl-faq details{background:#fff;border:1px solid var(--line);border-radius:13px}
.sl-faq summary{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:16px 20px;cursor:pointer;list-style:none;font-size:15px;font-weight:700;color:var(--ink)}
.sl-faq summary::-webkit-details-marker{display:none}
.sl-faq summary:hover{color:var(--blue)}
/* Two rules crossed, and the vertical one rotates away on open: a plus turning
   into a minus, drawn rather than swapped for a second icon. */
.sl-faq-x{position:relative;width:13px;height:13px;flex-shrink:0}
.sl-faq-x::before,.sl-faq-x::after{content:"";position:absolute;background:var(--slate-light);
  border-radius:2px;transition:transform .2s,background .13s}
.sl-faq-x::before{top:5.5px;left:0;width:13px;height:2px}
.sl-faq-x::after{left:5.5px;top:0;width:2px;height:13px}
.sl-faq details[open] .sl-faq-x::after{transform:rotate(90deg)}
.sl-faq summary:hover .sl-faq-x::before,.sl-faq summary:hover .sl-faq-x::after{background:var(--blue)}
.sl-faq p{font-size:14px;line-height:1.7;color:var(--slate);margin:0;padding:0 20px 18px}

/* ── The ask ── */


@media(prefers-reduced-motion:reduce){
  .sl-faq-x::before,.sl-faq-x::after,.sl-link svg{transition:none}
}

@media(max-width:1000px){
  /* Below the two-column hero the scene has nothing to sit beside, and a
     decorative illustration is not worth the width on a narrow screen. */
  .sl-faq-wrap{grid-template-columns:1fr;gap:0}
  .sl-faq-art{display:none}
  .sl-hero-in{grid-template-columns:1fr;gap:34px}
  .sl-rate{max-width:460px}
  .sl-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .sl-steps{grid-template-columns:repeat(2,minmax(0,1fr));gap:26px 20px}
  .sl-steps::before{display:none}
  .sl-payouts{grid-template-columns:1fr;gap:28px}
}
@media(max-width:700px){
  .sl-hero{padding:40px 0 46px}
  .sl-hero h1{font-size:32px}
  .sl-hero-copy>p{font-size:15px}
  .sl-rate{padding:20px 18px}
  .sl-rate-n span{font-size:54px}
  /* One straight line at every phone width. Set to never wrap, and sized so the
     three of them plus their ticks come in under the narrowest screen we
     support rather than folding the last one onto its own line. */
  .sl-assure{flex-wrap:nowrap;justify-content:space-between;gap:6px;margin-top:20px}
  .sl-assure li{gap:3px;font-size:10px;white-space:nowrap}
  .sl-assure svg{width:11px;height:11px}
  .sl-sec{padding:40px 0}
  .sl-head{margin-bottom:22px}
  .sl-head h2,.sl-pay-copy h2{font-size:23px}
  .sl-head p{font-size:14.5px}
  .sl-grid{grid-template-columns:1fr}
  .sl-steps{grid-template-columns:1fr;gap:22px}
  /* Three per line at any phone width. A grid, not wrapping flex: flex packs by
     content width, so "HTML" and "AI Tools" would sit four to a row while
     "JavaScript" dropped alone onto the next one. Equal columns give three,
     always, and the label clips rather than pushing the row apart. */
  .sl-cats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}
  .sl-cat{justify-content:center;gap:4px;padding:9px 5px;font-size:10.5px;border-radius:9px}
  .sl-cat svg{width:13px;height:13px}
  .sl-cta .btn{flex:1 1 auto;justify-content:center}

  /* The calculator stops being a table. Four columns of numbers on a phone is
     four columns of nothing legible, so each rung becomes its own small block:
     name on top, then the two figures side by side under it. */
  .sl-calc-top{padding:16px;gap:12px}
  .sl-presets{margin-left:0;width:100%}
  .sl-preset{flex:1 1 auto;text-align:center}
  .sl-rung{grid-template-columns:1fr 1fr;gap:10px 14px;padding:14px 16px}
  .sl-rung-id{grid-column:1 / -1}
  .sl-rung-bar{grid-column:1 / -1;order:3}
  .sl-rung-keep,.sl-rung-take{text-align:left;order:2}
  .sl-rung-take{text-align:right}
  .sl-calc-note{padding:14px 16px}
}

/* ============ Toasts ============ */
/* Stack up from the bottom right and slide in from off-screen. The stack itself
   ignores pointer events so it never blocks the page; each toast turns them
   back on for its own links and close button. */
.toast-stack{position:fixed;right:0;bottom:0;z-index:200;display:flex;flex-direction:column;align-items:flex-end;gap:10px;
  padding:0 max(18px,env(safe-area-inset-right)) calc(18px + env(safe-area-inset-bottom)) 18px;pointer-events:none;max-width:100%}
.toast{pointer-events:auto;display:flex;align-items:flex-start;gap:12px;width:340px;max-width:calc(100vw - 36px);
  background:#fff;color:var(--ink);padding:14px 14px 14px 16px;border-radius:14px;
  box-shadow:0 16px 44px rgba(10,17,48,.16);border:1px solid var(--line);
  transform:translateX(calc(100% + 24px));opacity:0;transition:transform .32s cubic-bezier(.22,1,.36,1),opacity .24s}
.toast.on{transform:translateX(0);opacity:1}
.toast-ic{width:26px;height:26px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;margin-top:1px}
.t-success .toast-ic{background:var(--green-wash);color:#0a7a56}
.t-info .toast-ic{background:var(--blue-wash);color:var(--blue)}
.t-error .toast-ic{background:#fdeaea;color:#c8352f}
.toast-body{flex:1;min-width:0}
.toast-title{font-weight:700;font-size:14px;line-height:1.3}
.toast-msg{font-size:12.5px;color:var(--slate);margin-top:3px;line-height:1.45;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.toast-action{display:inline-block;margin-top:9px;font-size:12.5px;font-weight:700;color:var(--blue)}
.toast-action:hover{color:var(--blue-deep);text-decoration:underline}
.toast-x{width:28px;height:28px;flex-shrink:0;border:0;background:none;color:var(--slate-light);border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center}
.toast-x:hover{background:var(--blue-tint);color:var(--ink)}
@media(max-width:480px){
  .toast-stack{left:0;align-items:stretch;padding-left:12px;padding-right:12px}
  .toast{width:auto;max-width:none}
}
@media(prefers-reduced-motion:reduce){.toast{transition:opacity .2s;transform:none}}

/* ============ Auth pages ============ */
.auth-body{display:grid;grid-template-columns:1.05fr 1fr;min-height:100vh}
.auth-aside{position:relative;background:linear-gradient(155deg,#000,#0d1b52 55%,#12206b);color:#fff;overflow:hidden;display:flex;align-items:center}
.auth-aside .hero-net{position:absolute;inset:0;width:100%;height:100%;opacity:.5}
.auth-aside-in{position:relative;z-index:2;padding:56px;max-width:520px}
.auth-aside-in h2{font-size:36px;font-weight:800;letter-spacing:-.03em;margin:26px 0 14px;line-height:1.15}
.auth-aside-in p{color:rgba(255,255,255,.68);font-size:15.5px;line-height:1.65}
.auth-aside-list{list-style:none;margin:22px 0 0;padding:0;display:flex;flex-direction:column;gap:11px}
.auth-aside-list li{display:flex;align-items:center;gap:10px;font-size:13.5px;color:rgba(255,255,255,.8)}
.auth-aside-list svg{color:#6ee7b7;flex-shrink:0}
.auth-aside-foot{position:absolute;left:56px;bottom:26px;font-size:12px;color:rgba(255,255,255,.4)}

/* Code grid backdrop: ruled lines with SDK snippets drifting up behind them. */
.codegrid{position:absolute;inset:0;overflow:hidden;z-index:0}
.cg-rule{position:absolute;inset:-1px;
  background-image:linear-gradient(rgba(120,160,255,.09) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(120,160,255,.09) 1px,transparent 1px);
  background-size:44px 44px}
.cg-stream{position:absolute;left:0;right:0;top:0;padding:26px 30px;font-family:var(--mono);font-size:12px;line-height:2.05;
  color:rgba(160,190,255,.30);white-space:pre;animation:cgdrift 46s linear infinite;will-change:transform}
.cg-line{display:flex;gap:14px}
.cg-num{color:rgba(140,170,255,.18);width:16px;text-align:right;flex-shrink:0}
.cg-stream code{font-family:inherit}
@keyframes cgdrift{from{transform:translateY(0)}to{transform:translateY(-50%)}}
.cg-fade{position:absolute;inset:0;background:linear-gradient(160deg,rgba(0,0,0,.15) 0%,rgba(4,8,30,.82) 55%,rgba(6,14,54,.94) 100%)}
.cg-glow{position:absolute;width:70%;aspect-ratio:1;left:-10%;bottom:-25%;border-radius:50%;
  background:radial-gradient(circle,rgba(47,92,255,.40),transparent 62%);filter:blur(20px)}
@media(prefers-reduced-motion:reduce){.cg-stream{animation:none}}

.auth-logo{display:inline-flex;align-items:center;font-weight:800;font-size:24px;letter-spacing:-.02em}
.auth-logo .logo-text{display:none}
.auth-logo.logo-fallback .auth-logo-img{display:none}
.auth-logo.logo-fallback .logo-text{display:inline-block}
.auth-logo .a{color:#fff}
.auth-logo .b{color:#6f97ff}
.auth-logo-img{height:46px;width:auto;aspect-ratio:977/160;display:block;object-fit:contain}
.auth-logo.sm{margin-bottom:26px}
.auth-logo.sm .auth-logo-img{height:34px}
.auth-logo.sm .a{color:var(--ink)}
.auth-logo.sm .b{color:var(--blue)}
.auth-main{display:flex;align-items:center;justify-content:center;padding:40px 24px;background:#fff}
.auth-card{width:100%;max-width:400px}
.auth-head h1{font-size:27px;font-weight:800;letter-spacing:-.02em}
.auth-head p{color:var(--slate);font-size:14.5px;margin-top:7px}
.auth-info{margin-top:20px;padding:12px 14px;border-radius:11px;background:var(--blue-tint);border:1px solid var(--line);font-size:12.5px;color:var(--ink-soft);line-height:1.55}
.auth-form{display:flex;flex-direction:column;gap:15px;margin-top:22px}
.auth-2col{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.auth-field{display:flex;flex-direction:column;gap:7px}
.auth-label{font-size:12px;font-weight:700;color:var(--ink-soft);letter-spacing:.02em}
.auth-label-row{display:flex;align-items:center;justify-content:space-between}
.auth-inwrap{position:relative}
.auth-input{width:100%;font:inherit;font-size:14.5px;padding:13px 15px;border:1px solid var(--line);border-radius:12px;background:#fff;color:var(--ink);transition:border-color .12s,box-shadow .12s}
.auth-input::placeholder{color:#a9adbb}
.auth-input:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(31,82,255,.1)}
.auth-inwrap .auth-input{padding-right:46px}
.auth-eye{position:absolute;right:6px;top:50%;transform:translateY(-50%);width:34px;height:34px;display:flex;align-items:center;justify-content:center;border-radius:9px;color:var(--slate-light);cursor:pointer;background:none;border:none}
.auth-eye:hover{color:var(--blue);background:var(--blue-tint)}
.auth-otp{text-align:center;font-family:var(--mono);font-size:20px;letter-spacing:.4em}
.auth-hint{font-size:11.5px;color:var(--slate-light);line-height:1.5}
.auth-btn{width:100%;justify-content:center;padding:14px;font-size:14.5px;margin-top:4px}
.auth-btn:disabled{opacity:.6;cursor:not-allowed}
.auth-error{padding:11px 14px;border-radius:11px;background:#fdeaea;border:1px solid #f6c9c9;color:#b3261e;font-size:13px;line-height:1.5}
.auth-ok{padding:11px 14px;border-radius:11px;background:var(--green-wash);border:1px solid #b8ead6;color:#0a7a56;font-size:13px;line-height:1.5}
.auth-note{color:var(--slate);font-size:13.5px;text-align:center}
/* Neutral sibling of .auth-error and .auth-ok, for context rather than an
   outcome: used where a screen has to explain itself before you act, such as
   the password reset that happens on Domzivo rather than here. */
.auth-callout{padding:11px 14px;border-radius:11px;background:var(--blue-tint);border:1px solid var(--line);margin-bottom:16px}
.auth-callout p{margin:0;color:var(--slate);font-size:13px;line-height:1.55}
.auth-link{color:var(--blue);font-weight:600;font-size:13.5px;background:none;border:none;cursor:pointer;padding:0}
.auth-link:hover{text-decoration:underline}
.auth-link.sm{font-size:12px}
.auth-alt{margin-top:22px;text-align:center;font-size:13.5px;color:var(--slate)}
@media(max-width:900px){.auth-body{grid-template-columns:1fr}.auth-aside{display:none}}

/* ============ Account menu in the navbar ============ */
.nav-auth{display:inline-flex;align-items:center;gap:9px}
.acct{position:relative}
.acct-btn{display:flex;align-items:center;gap:7px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);border-radius:30px;padding:5px 11px 5px 5px;color:#fff;cursor:pointer}
.acct-btn:hover{background:rgba(255,255,255,.14)}
.acct-avatar{width:30px;height:30px;border-radius:50%;background:linear-gradient(135deg,var(--blue),#7aa0ff);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:12.5px;flex-shrink:0}
/* An uploaded picture fills the badge and keeps its circle. The image is
   rounded to match rather than relying on overflow, since these badges are
   flex containers with no clipping. object-fit stops a non-square photo from
   stretching. The store settings badge has its own .set-avatar img rule. */
.acct-avatar img,.dash-avatar img{width:100%;height:100%;border-radius:50%;object-fit:cover;display:block}
.acct-menu{position:absolute;top:calc(100% + 12px);right:0;width:250px;background:#fff;border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow-lg);padding:7px;opacity:0;visibility:hidden;transform:translateY(-6px);transition:opacity .14s,transform .14s,visibility .14s;z-index:120}
.acct-menu.on{opacity:1;visibility:visible;transform:translateY(0)}
.acct-head{padding:11px 12px 12px;border-bottom:1px solid var(--line-soft);margin-bottom:6px}
.acct-name{font-weight:700;font-size:13.5px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.acct-email{font-size:11.5px;color:var(--slate-light);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:2px}
.acct-item{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:10px;font-size:13.5px;font-weight:600;color:var(--ink-soft)}
.acct-item:hover{background:var(--blue-tint);color:var(--blue)}
.acct-item.danger{color:#c8352f}
.acct-item.danger:hover{background:#fdeaea;color:#b3261e}
.m-user{display:flex;align-items:center;gap:11px;padding:12px;background:var(--blue-tint);border-radius:12px;margin-bottom:12px}
.m-user-t{min-width:0}

/* ============ Cart + checkout ============ */
.cart-page{padding:8px 0 64px}
/* ── Cart ────────────────────────────────────────────────────
   One list of lines with a bar on top, and a summary beside it that stays put
   while the list scrolls. */
.cart-grid{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:22px;align-items:start}
.cart-main{min-width:0;background:#fff;border:1px solid var(--line);border-radius:14px;overflow:hidden}

/* The bar belongs to the list, so the two whole-cart actions sit on the thing
   they act on rather than floating above the page. */
.cart-bar{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:11px 14px;background:var(--ink)}
.cart-bar-btn{display:inline-flex;align-items:center;gap:7px;padding:7px 14px;border-radius:8px;
  font:600 12.5px var(--sans);color:#fff;background:rgba(255,255,255,.12);border:0;cursor:pointer;
  transition:background .15s}
.cart-bar-btn:hover{background:rgba(255,255,255,.2);color:#fff}
.cart-bar-btn.danger:hover{background:#c8352f}

.cart-lines{display:flex;flex-direction:column}
.cl + .cl{border-top:1px solid var(--line)}
.cl-row{display:grid;grid-template-columns:88px minmax(0,1fr) auto auto 34px;gap:14px;
  align-items:start;padding:16px}
.cl-thumb{width:88px;height:66px;border-radius:8px;overflow:hidden;background:var(--blue-tint);
  color:var(--blue);display:flex;align-items:center;justify-content:center}
.cl-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.cl-main{min-width:0}
.cl-name{display:block;font-weight:700;font-size:14.5px;line-height:1.4;color:var(--blue);
  overflow-wrap:anywhere}
.cl-name:hover{text-decoration:underline}
.cl-by{font-size:12px;color:var(--slate-light);margin-top:3px}
.cl-terms{display:flex;flex-wrap:wrap;gap:4px 16px;margin-top:9px;font-size:12.5px;color:var(--slate)}
.cl-terms b{color:var(--ink);font-weight:700}
.cl-tag{font-size:11px;font-weight:700;color:#0a7a56;background:var(--green-wash);
  border-radius:20px;padding:1px 9px}

.cl-qty{display:flex;flex-direction:column;align-items:center;gap:5px}
.cl-qty-l{font-size:11.5px;color:var(--slate-light);font-weight:600}
.cl-qty .qty-in{width:58px;height:32px;text-align:center;font-family:var(--mono);font-size:13px;
  border:1px solid var(--line);border-radius:8px;background:#fff;color:var(--ink)}
.cl-qty .qty-in:focus{outline:none;border-color:var(--blue)}
.cl-each{font-size:11px;color:var(--slate-light);font-family:var(--mono)}

.cl-price{font-weight:800;font-size:26px;letter-spacing:-.02em;color:var(--ink);
  min-width:82px;text-align:right;line-height:1}
/* The sign rides above the digits, so the number itself is what the eye lands on. */
.cl-price sup{font-size:14px;font-weight:700;vertical-align:super;margin-right:1px}
.cl-price .free{color:var(--green);font-size:17px}
.cl-x{width:34px;height:34px;border-radius:9px;display:flex;align-items:center;justify-content:center;
  color:var(--slate-light);background:none;border:0;cursor:pointer}
.cl-x:hover{color:#c8352f;background:#fdeaea}

/* The support add-on, attached under the line it belongs to. */
.cl-ext{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 16px 16px;
  padding:11px 14px;background:var(--blue-tint);border:1px solid var(--line);border-radius:10px;
  font-size:12.5px;color:var(--ink-soft);cursor:pointer}
.cl-ext input{width:15px;height:15px;flex-shrink:0;accent-color:var(--blue);cursor:pointer;margin:0}
.cl-ext b{font-weight:700;color:var(--ink)}
.cl-ext-learn{margin-left:auto;font-size:12px;font-weight:600;color:var(--blue);white-space:nowrap}
.cl-ext-learn:hover{text-decoration:underline}

/* ── Summary ── */
.cart-summary{background:#fff;border:1px solid var(--line);border-radius:14px;padding:22px;
  position:sticky;top:calc(var(--nav-h) + 16px);text-align:center}
.cart-summary h2{font-size:15px;font-weight:700;color:var(--slate);margin-bottom:8px}
.cart-total{font-size:38px;font-weight:800;letter-spacing:-.03em;color:var(--ink);line-height:1}
.cart-total sup{font-size:20px;font-weight:700;vertical-align:super;margin-right:2px}
.cart-total-note{font-size:12.5px;color:var(--slate-light);margin:8px 0 0}
/* Green, and only here: it is the one button on the page that takes money. */
.cart-checkout{width:100%;justify-content:center;margin-top:18px;background:var(--green);color:#fff;
  border-color:var(--green);font-size:15px;padding:13px 20px}
.cart-checkout:hover{background:#0fa06f;border-color:#0fa06f;color:#fff}
.cart-tax{font-size:12px;line-height:1.6;color:var(--slate-light);margin:12px 0 0}
.cart-tax a{color:var(--slate);text-decoration:underline;text-underline-offset:2px}
/* One line, pushed to the two edges: Secure checkout left, Instant delivery
   right. Stacked they read as a list of two, which is more weight than a pair
   of reassurances deserves under the button. */
.cart-assure{display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:18px;padding-top:15px;border-top:1px solid var(--line-soft);text-align:left}
.cart-assure div{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--slate);
  font-weight:600;white-space:nowrap;min-width:0}
.cart-assure svg{color:var(--blue);flex-shrink:0}

@media(max-width:960px){
  .cart-grid{grid-template-columns:1fr}
  .cart-summary{position:static}
}
@media(max-width:620px){
  /* Flex, not grid. As a grid the price was placed in column 3, which is the
     34px remove-button column, so it was squeezed to nothing and never showed.

     Then two rows, not one. Sharing a single line, the stepper and the price
     took most of the width and left the title in a column barely wider than a
     phone number, wrapping it after every second word. The ::after is a
     zero-height full-width flex item ordered between the two groups, which
     forces the wrap: thumb, title and the X on top, quantity and price below.
     The title now gets the whole card, so it runs straight and the seller and
     licence lines under it stretch instead of folding. */
  .cl-row{display:flex;flex-wrap:wrap;align-items:flex-start;gap:10px;padding:11px 12px}
  .cl-row::after{content:'';flex-basis:100%;height:0;order:1}
  .cl-thumb{order:0;width:58px;height:44px;border-radius:6px;flex-shrink:0}
  .cl-main{order:0;flex:1 1 0;min-width:0}
  .cl-x{order:0;width:28px;height:28px;border-radius:7px;flex-shrink:0;margin-left:auto}
  .cl-qty{order:2;flex:0 0 auto;flex-direction:row;align-items:center;gap:8px}
  .cl-price{order:3;margin-left:auto;text-align:right;font-size:18px;min-width:0}
  .cl-price sup{font-size:11px}
  .cl-price .free{font-size:14px}

  /* One straight line, cut with an ellipsis. A title long enough to wrap is
     long enough that its first line already says which item this is, and the
     full text is one tap away on the item page. */
  .cl-name{font-size:13.5px;line-height:1.35;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis;overflow-wrap:normal}
  .cl-by{font-size:11.5px;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .cl-terms{gap:2px 12px;margin-top:5px;font-size:11.5px}
  .cl-terms span{white-space:nowrap}
  .cl-qty-l{font-size:11px}
  .cl-qty .qty-in{width:48px;height:28px;font-size:12.5px}
  .cl-each{font-size:10.5px}
  .cl-ext{margin:0 12px 11px;padding:8px 10px;font-size:11.5px;gap:8px;border-radius:8px}
  .cl-ext-learn{margin-left:0;flex:1 1 100%;font-size:11.5px}
  .cart-total{font-size:32px}
  .cart-bar{padding:9px 11px}
  .cart-bar-btn{padding:6px 11px;font-size:12px}

  /* Stretched left and right: 24px of page padding each side on a 360px phone
     is 13% of the screen given to nothing, and the card corners are squared off
     against the edge so the list uses the full width. */
  .cart-page .wrap{padding-left:0;padding-right:0}
  .cart-main{border-radius:0;border-left:0;border-right:0}
  .cart-grid{gap:12px}
  .cart-summary{padding:16px;border-radius:0;border-left:0;border-right:0}
  .cart-page .crumbs{padding-left:12px;padding-right:12px}
  .cart-page .empty{margin-left:12px;margin-right:12px}
}
@media(max-width:900px){.cart-grid{grid-template-columns:1fr}.cart-summary{position:static;order:2}}

/* ============ Checkout ============ */
/* Stacked cards down the left, a summary that follows the scroll on the right.
   Billing sits first because it is the one thing here the buyer may have to
   leave and fix, and finding that out after picking a card is a worse order to
   find it out in. */
.co-page{padding:26px 0 66px}
.co-grid{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:22px;align-items:start}
.co-col{display:flex;flex-direction:column;gap:16px;min-width:0}
.co-col>.auth-error{margin:0}

.co-card{background:#fff;border:1px solid var(--line);border-radius:14px;overflow:hidden}
.co-card-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:15px 20px;border-bottom:1px solid var(--line)}
.co-card-head h2{font-size:17px;font-weight:800;letter-spacing:-.01em}
.co-edit{font-size:12.5px;font-weight:700;color:var(--ink-soft);background:var(--line-soft);
  border:1px solid var(--line);border-radius:8px;padding:5px 13px;flex-shrink:0}
.co-edit:hover{background:var(--blue-wash);border-color:#c9d2ea;color:var(--blue)}
.co-card-body{padding:18px 20px}
.co-note{color:var(--slate);font-size:14px;line-height:1.65}

/* ── Billing ── */
.co-bill{display:flex;flex-direction:column;gap:2px;font-size:14px;line-height:1.6;color:var(--ink-soft)}
.co-bill b{font-size:14.5px;font-weight:700;color:var(--ink);margin-bottom:2px}
.co-bill-ph{font-family:var(--mono);font-size:13px;color:var(--slate);margin-top:4px}
.co-bill-note{margin-top:13px;font-size:12px;color:var(--slate-light);line-height:1.6}
.co-bill-none b{display:block}
.co-bill-none span{display:block;font-size:13.5px;color:var(--slate)}
.co-bill-none p{margin-top:9px;font-size:13px;color:var(--slate);line-height:1.6}
.co-bill-none a{color:var(--blue);font-weight:600}
.co-bill-none a:hover{text-decoration:underline}
/* Opens with the shape of an address in it rather than a blank card, which
   reads as a page that failed rather than one that is still loading. */
.co-bill-skel{display:flex;flex-direction:column;gap:8px}
.co-bill-skel span{height:12px;border-radius:5px;
  background:linear-gradient(90deg,var(--line-soft),#e9eaf0,var(--line-soft));
  background-size:200% 100%;animation:coskel 1.1s linear infinite}
.co-bill-skel span:nth-child(1){width:42%}
.co-bill-skel span:nth-child(2){width:64%}
.co-bill-skel span:nth-child(3){width:30%}
@keyframes coskel{to{background-position:-200% 0}}

/* ── Payment method: tabs pick, one panel explains ── */
.co-tabs{display:flex;border-bottom:1px solid var(--line);overflow-x:auto;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.co-tabs::-webkit-scrollbar{display:none}
.co-tab{display:flex;align-items:center;gap:7px;flex-shrink:0;white-space:nowrap;
  padding:13px 17px;font-family:inherit;font-size:13.5px;font-weight:600;color:var(--slate);
  background:none;border:0;border-bottom:3px solid transparent;cursor:pointer;
  transition:color .12s,border-color .12s}
.co-tab:hover{color:var(--ink)}
.co-tab.is-on{color:var(--blue);border-bottom-color:var(--blue)}
.co-tab svg{flex-shrink:0}

.co-panels{padding:28px 20px 24px}
.co-panel{display:none}
.co-panel.is-on{display:block}
.co-brand{text-align:center;margin-bottom:16px}
.co-brand-mark{font-size:23px;font-weight:800;letter-spacing:-.035em;color:var(--ink)}
.co-brand-mark b{color:var(--blue);font-weight:800}
.co-panel-lead{max-width:520px;margin:0 auto;text-align:center;font-size:14px;line-height:1.65;
  color:var(--slate)}

.co-accepts{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px;margin-top:18px}
.co-accepts-l{font-size:12.5px;color:var(--slate);margin-right:3px}
.pay-logo{display:inline-flex;align-items:center;justify-content:center;height:27px;padding:0 10px;
  background:#fff;border:1px solid var(--line);border-radius:5px;font-size:10.5px;font-weight:800;
  color:var(--slate);letter-spacing:.02em}
.pay-logo.visa{color:#1a1f71;font-size:12.5px;font-style:italic;letter-spacing:-.03em}
.pay-logo.mc{padding:0 12px}
.pay-logo.mc i{width:15px;height:15px;border-radius:50%;background:#eb001b}
.pay-logo.mc i+i{background:#f79e1b;margin-left:-6px;mix-blend-mode:multiply}
.pay-logo.verve{color:#0a8f45;font-size:12px;letter-spacing:-.01em}
.pay-logo.coin{font-family:var(--mono);font-size:11px;color:var(--ink)}
/* Not brands, just what else the gateway will take, so they read as words. */
.pay-logo.bank,.pay-logo.ussd,.pay-logo.momo{font-weight:600;font-size:11.5px;letter-spacing:0}
.pay-logo.more{border:0;background:none;color:var(--slate-light);font-weight:600;font-size:11.5px;padding:0 2px}

.co-balance{margin:18px auto 0;max-width:520px;text-align:center;padding:11px 15px;border-radius:10px;
  background:var(--blue-tint);border:1px solid var(--line);font-size:13px;line-height:1.6;color:var(--ink-soft)}
.co-balance b{font-weight:800;color:var(--ink)}
.co-balance.ok{background:var(--green-wash);border-color:#c6ecdc;color:#0a6b4b}
.co-balance.ok b{color:#0a6b4b}
.co-balance.short{background:#fdeaea;border-color:#f6cfcf;color:#a12b26}
.co-balance.short b{color:#a12b26}
.co-balance a{color:var(--blue);font-weight:700;text-decoration:underline;text-underline-offset:2px}
.co-fx{max-width:520px;margin:14px auto 0;text-align:center;font-size:12px;line-height:1.6;color:var(--slate-light)}

/* ── Your order ── */
.co-order{background:#fff;border:1px solid var(--line);border-radius:14px;overflow:hidden}
.co-order>summary{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:15px 20px;cursor:pointer;list-style:none}
.co-order>summary::-webkit-details-marker{display:none}
.co-order>summary:hover .co-order-t{color:var(--blue-deep)}
.co-order-t{display:flex;align-items:center;gap:9px;font-size:16px;font-weight:800;color:var(--blue)}
.co-chev{flex-shrink:0;transition:transform .18s}
.co-order[open] .co-chev{transform:rotate(90deg)}
.co-order-total{font-size:17px;font-weight:800;color:var(--ink)}
.co-lines{padding:0 20px;border-top:1px solid var(--line)}
.co-line{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:13px 0;
  border-bottom:1px solid var(--line-soft)}
.co-line-m{min-width:0}
.col-name{font-weight:600;font-size:14px;line-height:1.45}
.col-q{font-family:var(--mono);font-size:12px;color:var(--blue);background:var(--blue-wash);
  padding:1px 7px;border-radius:20px;margin-left:5px}
.col-meta{font-size:12px;color:var(--slate);margin-top:3px}
.col-price{font-weight:700;font-size:14.5px;white-space:nowrap}
.co-foot{padding:2px 20px 16px}
.co-foot-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 0;
  font-size:13.5px;color:var(--slate)}
.co-foot-row.total{border-top:1px solid var(--line);margin-top:3px;padding-top:13px;
  font-size:16px;font-weight:800;color:var(--ink)}

/* The fee is genuinely zero, which is worth a line rather than a silence: every
   marketplace the buyer has used before adds one here. */
.co-info{display:inline-flex;align-items:center;vertical-align:-2px;margin-left:3px;padding:0;
  color:var(--blue);background:none;border:0;cursor:pointer}
.co-info:hover{color:var(--blue-deep)}
/* The tip hangs off the ROW, not off the icon. Anchored to the icon it was a
   fixed-width box centred on a 13px target sitting near one edge of the screen,
   so on a phone half of it was outside the viewport and cut off. Pinned to the
   row's own left and right edges it can never be wider than the space it has. */
.co-foot-row,.co-sum-row{position:relative}
.co-info::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 7px);left:0;right:0;
  max-width:330px;padding:9px 12px;border-radius:9px;background:var(--ink);color:#fff;
  font-size:11.5px;font-weight:500;line-height:1.55;text-align:left;
  opacity:0;visibility:hidden;transition:opacity .14s;z-index:6;pointer-events:none;
  box-shadow:0 6px 20px rgba(10,17,48,.22)}
.co-info:hover::after,.co-info:focus-visible::after,.co-info.is-open::after{opacity:1;visibility:visible}
/* A tap is the only way in on a phone, where there is no hover to give. */
@media(hover:none){.co-info:hover::after{opacity:0;visibility:hidden}
  .co-info.is-open::after{opacity:1;visibility:visible}}

/* ── Summary rail ── */
.co-side{position:sticky;top:calc(var(--nav-h) + 16px);display:flex;flex-direction:column;gap:12px;min-width:0}
.co-sum{background:#fff;border:1px solid var(--line);border-radius:14px;padding:20px}
.co-sum h2{font-size:17px;font-weight:800;letter-spacing:-.01em;padding-bottom:13px;
  border-bottom:1px solid var(--line)}
.co-sum-lines{display:flex;flex-direction:column}
.co-sum-line{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 0;
  border-bottom:1px solid var(--line-soft);font-size:13.5px}
/* One line each, clipped. A summary that wraps is not a summary. */
.co-sum-n{min-width:0;color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.co-sum-n b{font-family:var(--mono);font-size:11.5px;color:var(--blue)}
.co-sum-p{flex-shrink:0;font-weight:700}
.co-sum-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 0;
  font-size:13.5px;color:var(--slate);border-bottom:1px solid var(--line)}
.co-sum-total{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding-top:14px;
  font-size:17px;font-weight:800}
.co-sum-amt{font-size:22px;font-weight:800;letter-spacing:-.025em}
.co-sum-note{margin-top:6px;font-size:12px;color:var(--slate-light)}
/* Green, and only here: it is the one button on the page that takes money. */
.co-pay-btn{width:100%;justify-content:center;margin-top:16px;background:var(--green);color:#fff;
  border-color:var(--green);font-size:15px;padding:13px 20px}
.co-pay-btn:hover{background:#0fa06f;border-color:#0fa06f;color:#fff}
.co-pay-btn:disabled{opacity:.65;cursor:default}
.co-back{display:block;text-align:center;margin-top:11px;font-size:13px;color:var(--slate);
  text-decoration:underline;text-underline-offset:2px}
.co-back:hover{color:var(--ink)}
.co-assure{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:0 4px;
  font-size:12.5px;color:var(--slate)}
.co-assure span{display:flex;align-items:center;gap:6px}
.co-assure svg{color:var(--green);flex-shrink:0}
.co-tax{padding:0 4px;font-size:12px;line-height:1.6;color:var(--slate-light)}
.co-tax a{color:var(--slate);text-decoration:underline;text-underline-offset:2px}

@media(max-width:900px){
  .co-grid{grid-template-columns:1fr}
  .co-side{position:static}
}
@media(max-width:620px){
  /* Edge to edge, the same as the cart: 24px of page padding each side on a
     360px phone is 13% of the screen given to nothing. */
  .co-page{padding:14px 0 44px}
  .co-page .wrap{padding-left:0;padding-right:0}
  .co-page .crumbs{padding-left:12px;padding-right:12px}
  .co-page .empty{margin-left:12px;margin-right:12px}
  .co-card,.co-order,.co-sum{border-radius:0;border-left:0;border-right:0}
  .co-grid,.co-col{gap:12px}
  .co-card-head{padding:13px 14px}
  .co-card-head h2{font-size:15.5px}
  .co-card-body{padding:14px}
  .co-tab{padding:11px 13px;font-size:12.5px;gap:6px}
  .co-panels{padding:20px 14px 18px}
  .co-brand-mark{font-size:19px}
  .co-panel-lead{font-size:13px}
  .co-balance,.co-fx{font-size:12px}
  .co-order>summary{padding:13px 14px}
  .co-order-t,.co-order-total{font-size:15px}
  .co-lines{padding:0 14px}
  .co-foot{padding:2px 14px 13px}
  .co-sum{padding:16px 14px}
  .co-sum-amt{font-size:20px}
  .co-assure,.co-tax{padding-left:14px;padding-right:14px}
  .co-assure{font-size:12px}
}

/* ============ Payment verify ============ */
.verify-page{padding:70px 0}
.vf-card{max-width:520px;margin:0 auto;background:#fff;border:1px solid var(--line);border-radius:20px;padding:44px 34px;text-align:center;box-shadow:var(--shadow-lg)}
.vf-state h1{font-size:24px;font-weight:800;letter-spacing:-.02em;margin-bottom:10px}
.vf-state p{color:var(--slate);font-size:14.5px;line-height:1.65;max-width:400px;margin:0 auto}
.vf-spin{width:46px;height:46px;border-radius:50%;border:3px solid var(--blue-wash);border-top-color:var(--blue);margin:0 auto 22px;animation:vfspin .8s linear infinite}
@keyframes vfspin{to{transform:rotate(360deg)}}
.vf-ic{width:66px;height:66px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 20px}
.vf-ic.ok{background:var(--green-wash);color:var(--green)}
.vf-ic.wait{background:#fff5e5;color:var(--amber)}
.vf-ic.bad{background:#fdeaea;color:#c8352f}
.vf-actions{display:flex;gap:11px;justify-content:center;margin-top:24px;flex-wrap:wrap}
.vf-ref{margin-top:26px;font-size:11.5px;color:var(--slate-light)}
@media(prefers-reduced-motion:reduce){.vf-spin{animation-duration:2.4s}}

/* ============ Account pages ============ */
.acct-page{padding:8px 0 64px}
/* The tabs never compress. Flex items shrink by default, so on a phone
   "My licenses" and "My orders" were squeezed until the label wrapped under its
   own icon. They now hold their size and the row scrolls sideways instead, so
   every tab stays on one line at any width. */
.acct-tabs{display:flex;gap:8px;border-bottom:1px solid var(--line);margin-bottom:26px;
  overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.acct-tabs::-webkit-scrollbar{display:none}
.acct-tab{display:inline-flex;align-items:center;gap:8px;padding:12px 16px;font-size:14px;font-weight:700;
  color:var(--slate);border-bottom:2px solid transparent;margin-bottom:-1px;
  flex-shrink:0;white-space:nowrap}
.acct-tab svg{flex-shrink:0}
.acct-tab:hover{color:var(--blue)}
.acct-tab.on{color:var(--blue);border-bottom-color:var(--blue)}
/* Tighter on a phone so all three usually fit without needing the scroll. */
@media(max-width:520px){
  .acct-tabs{gap:2px}
  .acct-tab{padding:11px 10px;font-size:13px;gap:6px}
}
.acct-loading{display:flex;flex-direction:column;gap:12px}
.sk-row{height:104px;border-radius:14px;background:linear-gradient(90deg,#f2f4f8 25%,#e9ecf3 37%,#f2f4f8 63%);background-size:400% 100%;animation:sk 1.3s ease infinite}
@keyframes sk{0%{background-position:100% 50%}100%{background-position:0 50%}}
@media(prefers-reduced-motion:reduce){.sk-row{animation:none}}
/* Placeholder for a figure that has not arrived. Replaces a literal "-", which
   did not read as loading: it read as "the value is nothing", so the number
   appearing a moment later looked like a correction. */
.sk-num{display:inline-block;width:2.2em;height:.72em;border-radius:4px;vertical-align:baseline;
  background:linear-gradient(90deg,#f2f4f8 25%,#e9ecf3 37%,#f2f4f8 63%);background-size:400% 100%;
  animation:sk 1.3s ease infinite}
@media(prefers-reduced-motion:reduce){.sk-num{animation:none}}
.lic-list,.ord-list{display:flex;flex-direction:column;gap:12px}
.lic-card,.ord-card{background:#fff;border:1px solid var(--line);border-radius:16px;padding:20px}
/* A licence: thumbnail, what it is, and what you can do with it, in one row.
   Desktop and tablet read left to right; phones stack, further down. */
.lic-card{display:flex;align-items:flex-start;gap:16px;padding:16px}
.lic-thumb{width:92px;height:69px;flex-shrink:0;border-radius:9px;overflow:hidden;
  background:var(--blue-tint);color:var(--blue);display:flex;align-items:center;justify-content:center}
.lic-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.lic-id{flex:1;min-width:0}
.lic-name-row{display:flex;align-items:flex-start;gap:9px}
.lic-name{font-weight:700;font-size:15px;letter-spacing:-.012em;color:var(--ink);
  text-decoration:none;line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
a.lic-name:hover{color:var(--blue)}
.lic-meta{font-size:12px;color:var(--slate);margin-top:4px;text-transform:capitalize;line-height:1.5}
/* Support has a state, so it says so in colour rather than making the reader
   parse "until" against "ended". */
.lic-sup{font-weight:600;color:#0a7a56}
.lic-sup.is-over{color:var(--slate-light);font-weight:500}

/* The domains a licence is installed on. A domain is not prose, so it opts out
   of the capitalize the surrounding meta line applies and keeps its own case. */
.lic-installs{display:flex;align-items:center;flex-wrap:wrap;gap:6px;text-transform:none}
.lic-installs svg{flex-shrink:0;color:var(--slate-light)}
.lic-domain-n{font-family:var(--mono);font-size:11.5px;color:var(--ink);word-break:break-all}
.lic-env{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;
  color:var(--slate);background:var(--blue-tint);border-radius:20px;padding:1px 6px}

/* Seller side: the same information as a block, since a seller is auditing
   rather than glancing and may be looking at several domains at once. */
.lic-domains{margin-top:8px;display:flex;flex-direction:column;gap:5px}
.lic-domains.empty{font-size:11.5px;color:var(--slate-light);font-style:italic;margin-top:7px}
.lic-domain{display:flex;align-items:center;flex-wrap:wrap;gap:7px;font-size:12px}
.lic-domain svg{flex-shrink:0;color:var(--slate-light)}
.lic-domain.off{opacity:.55}
.lic-domain.off .lic-domain-n{text-decoration:line-through}
.lic-domain-t{color:var(--slate-light);font-size:11px;margin-left:auto;white-space:nowrap}

.lic-badge{font-size:10.5px;font-weight:700;padding:3px 9px;border-radius:20px;
  text-transform:capitalize;flex-shrink:0;white-space:nowrap}
.lic-badge.s-active,.lic-badge.s-completed,.lic-badge.s-published,.lic-badge.s-approved,.lic-badge.s-paid,.lic-badge.s-visible{background:var(--green-wash);color:#0a7a56}
.lic-badge.s-pending,.lic-badge.s-pending_review{background:#fff5e5;color:#a26a05}
.lic-badge.s-draft{background:#f1f3f8;color:var(--slate)}
.lic-badge.s-suspended,.lic-badge.s-failed,.lic-badge.s-revoked,.lic-badge.s-refunded,.lic-badge.s-cancelled,.lic-badge.s-rejected,.lic-badge.s-removed{background:#fdeaea;color:#b3261e}

/* ── Actions ── */
.lic-side{display:flex;align-items:flex-start;gap:8px;flex-shrink:0}
.lic-side .btn{padding:10px 16px;font-size:13.5px}
.lic-ask{white-space:nowrap}
.lic-ask:disabled{opacity:.5;cursor:not-allowed}

/* One button, one menu: getting the file and getting the code are the same
   errand, and they were competing for room as two controls plus a strip. */
.lic-dl{position:relative}
.lic-dl-btn{gap:6px}
.lic-caret{transition:transform .16s;margin-left:-1px}
.lic-dl-btn[aria-expanded="true"] .lic-caret{transform:rotate(180deg)}
.lic-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:30;min-width:236px;
  background:#fff;border:1px solid var(--line);border-radius:12px;padding:6px;
  box-shadow:0 12px 32px rgba(10,17,48,.16)}
.lic-menu-i{display:flex;align-items:center;gap:10px;width:100%;text-align:left;
  font-family:inherit;font-size:13px;font-weight:600;color:var(--ink);background:none;border:0;
  padding:9px 10px;border-radius:8px;cursor:pointer}
.lic-menu-i svg{width:16px;height:16px;flex-shrink:0;color:var(--slate-light)}
.lic-menu-i:hover{background:var(--blue-tint);color:var(--blue)}
.lic-menu-i:hover svg{color:var(--blue)}
.lic-menu-i.is-off{color:var(--slate-light);cursor:default}
.lic-menu-i.is-off:hover{background:none;color:var(--slate-light)}
.lic-menu-code{display:flex;align-items:center;gap:8px;margin-top:5px;padding:8px 10px;
  border-top:1px solid var(--line-soft)}
.lic-menu-code code{flex:1;min-width:0;font-family:var(--mono);font-size:11.5px;font-weight:700;
  color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Masked, the dots are spacing rather than characters to read. */
.lic-menu-code code.is-masked{color:var(--slate-light);letter-spacing:.14em}
.lic-eye{flex-shrink:0;font-family:inherit;font-size:11.5px;font-weight:700;color:var(--blue);
  background:none;border:0;padding:4px 7px;cursor:pointer;border-radius:6px}
.lic-eye:hover{background:var(--blue-wash)}
.lic-eye:focus-visible{outline:2px solid var(--blue);outline-offset:1px}

/* Tablet: the row holds, but the buttons stack so a long title keeps its width. */
@media(max-width:900px){
  .lic-side{flex-direction:column;align-items:stretch}
  .lic-side .btn{justify-content:center}
  .lic-menu{min-width:214px}
}
/* Phone: stacked. A three-part row inside 312px gives the title about 90px, and
   at that width every real item name is four lines of two words. */
@media(max-width:700px){
  .lic-card{flex-wrap:wrap;gap:12px;padding:14px}
  .lic-thumb{width:64px;height:48px}
  .lic-id{flex:1 1 0}
  .lic-name{font-size:13.5px}
  .lic-meta{font-size:11.5px}
  .lic-side{flex:1 1 100%;flex-direction:row;align-items:stretch;gap:8px}
  .lic-dl{flex:1}
  .lic-dl-btn{width:100%;justify-content:center}
  .lic-ask{flex:1;justify-content:center}
  .lic-side .btn{padding:10px 12px;font-size:12.5px}
  /* Anchored to the left edge of the card rather than the button, so a menu
     under a half-width button still has room for its longest label. */
  .lic-menu{left:0;right:auto;min-width:0;width:calc(200% + 8px)}
}
/* Tighter than a licence card. An order is a receipt: a number, a date, a line
   per item and a total. It was carrying the padding and type size of something
   you read, when it is something you glance at to check a figure. Roughly a
   quarter of the height has come out without changing what is on it. */
.ord-card{padding:14px 16px}
.ord-list{gap:10px}
.ord-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
  padding-bottom:10px;border-bottom:1px solid var(--line-soft)}
.ord-num{font-weight:800;font-size:13px}
.ord-date{font-size:11.5px;color:var(--slate);margin-top:2px}
.ord-items{padding:2px 0}
.ord-item{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:6px 0;
  font-size:12.5px;color:var(--ink-soft)}
.ord-tier{font-size:10.5px;color:var(--slate);text-transform:capitalize;background:var(--blue-wash);
  padding:1px 6px;border-radius:20px;margin-left:5px}
.ord-foot{display:flex;align-items:center;justify-content:space-between;padding-top:9px;
  border-top:1px solid var(--line-soft);font-size:13px;font-weight:700}
.ord-total{font-size:14.5px;font-weight:800}
@media(max-width:700px){
  .ord-card{padding:12px 13px}
  .ord-item{font-size:12px;padding:5px 0}
}

/* ============ Product reviews ============ */
.rv-bars{display:flex;flex-direction:column;gap:5px;margin-bottom:10px}
.rv-bar-row{display:flex;align-items:center;gap:9px;font-size:11.5px;color:var(--slate)}
.rv-bar-l{width:9px;font-weight:700;color:var(--ink-soft)}
.rv-bar{flex:1;height:7px;background:#e8ebf2;border-radius:20px;overflow:hidden}
.rv-bar-fill{display:block;height:100%;background:var(--amber);border-radius:20px}
.rv-bar-n{width:26px;text-align:right;font-family:var(--mono)}
.rv-verified-note{font-size:12.5px;color:var(--slate-light)}
.rv-write{margin-top:22px;padding:22px;background:#fff;border:1px solid var(--line);border-radius:16px}
.rv-write h3{font-size:16px;font-weight:800;margin-bottom:6px}
.rv-stars-pick{display:flex;align-items:center;gap:4px;margin:16px 0 12px;flex-wrap:wrap}
.rv-star{font-size:27px;line-height:1;color:#d8dbe4;background:none;border:none;cursor:pointer;padding:0 2px;transition:color .1s}
.rv-star.on{color:var(--amber)}
.rv-pick-label{margin-left:10px;font-size:13px;font-weight:600;color:var(--slate)}
.rv-write textarea{resize:vertical;min-height:96px}
.rv-write-actions{display:flex;gap:10px;margin-top:14px;flex-wrap:wrap}
.rv-signin{margin-top:20px;padding:14px 16px;background:var(--blue-tint);border:1px solid var(--line);border-radius:12px;font-size:13.5px;color:var(--slate)}
.rv-empty{margin-top:20px;padding:26px;text-align:center;font-size:13.5px;color:var(--slate);background:var(--blue-tint);border-radius:14px}
.rv-list{display:flex;flex-direction:column;gap:2px;margin-top:22px}
.rv-item{display:flex;gap:14px;padding:18px 0;border-bottom:1px solid var(--line-soft)}
.rv-item:last-child{border-bottom:none}
.rv-av{width:38px;height:38px;border-radius:50%;background:var(--blue-wash);color:var(--blue);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:14px;flex-shrink:0}
.rv-main{flex:1;min-width:0}
.rv-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.rv-name{font-weight:700;font-size:14px}
.rv-badge{font-size:10.5px;font-weight:700;color:#0a7a56;background:var(--green-wash);padding:2px 8px;border-radius:20px}
.rv-date{font-size:12px;color:var(--slate-light);margin-left:auto}
.rv-rating{margin-top:5px;font-size:13px}
.rv-body{margin-top:8px;font-size:14px;line-height:1.65;color:var(--ink-soft);white-space:pre-wrap}
@media(max-width:520px){.rv-date{margin-left:0;width:100%}}

/* ============ Seller dashboard ============ */
.dash-body{display:flex;min-height:100vh;background:var(--blue-tint)}
/* 208 rather than 250. The longest label here is "Store settings", about 88px
   at this size, so 250 was carrying roughly 60px of empty gutter down the whole
   height of the page and taking it straight off the content beside it. */
.dash-side{width:208px;flex-shrink:0;background:var(--ink);color:#fff;display:flex;flex-direction:column;padding:16px 11px;position:sticky;top:0;height:100vh;overflow-y:auto}
.dash-side-head{display:flex;align-items:center;justify-content:space-between;padding:4px 6px 15px}
.dash-side-head .logo-img{height:28px}
/* Fallback text, if the image ever fails to load on this dark ground. */
.dash-side-head .logo-text .a{color:#fff}
.dash-side-head .logo-text .b{color:#6f97ff}
.dash-side-close{display:none;color:rgba(255,255,255,.6)}
.dash-store{display:flex;align-items:center;gap:9px;padding:10px;background:rgba(255,255,255,.06);border-radius:11px;margin-bottom:15px}
.dash-store-av{width:34px;height:34px;border-radius:10px;background:linear-gradient(135deg,var(--blue),#7aa0ff);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:15px;flex-shrink:0;overflow:hidden}
/* Rounded to 10px rather than a circle, matching the badge it sits in. */
.dash-store-av img{width:100%;height:100%;object-fit:cover;display:block}
.dash-store-t{min-width:0}
.dash-store-n{font-weight:700;font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dash-store-s{font-size:11px;color:#7ef0c0;text-transform:capitalize;margin-top:1px}
.dash-nav-label{font-size:9.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.32);padding:0 8px 7px}
.dash-nav{display:flex;flex-direction:column;gap:2px;flex:1}
.dash-link{display:flex;align-items:center;gap:10px;padding:10px 11px;border-radius:9px;font-size:13px;font-weight:600;color:rgba(255,255,255,.62);white-space:nowrap}
.dash-link svg{flex-shrink:0;opacity:.8}
.dash-link:hover{background:rgba(255,255,255,.07);color:#fff}
.dash-link.on{background:var(--blue);color:#fff}
.dash-link.on svg{opacity:1}
.dash-link.danger{color:#ff9ba0}
.dash-link.danger:hover{background:rgba(229,72,77,.14);color:#ff8b8f}
.dash-side-foot{display:flex;flex-direction:column;gap:2px;padding-top:14px;margin-top:10px;border-top:1px solid rgba(255,255,255,.08)}
.dash-main{flex:1;min-width:0;display:flex;flex-direction:column}
/* Kept compact: this bar is sticky, so every pixel here is taken away from the
   content for the whole scroll, not just at the top. */
.dash-top{display:flex;align-items:center;gap:16px;padding:12px 24px;background:#fff;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:60}
.dash-burger{display:none;background:var(--blue-tint);color:var(--ink)}
.dash-title{flex:1;min-width:0}
.dash-title h1{font-size:17px;font-weight:800;letter-spacing:-.02em;line-height:1.25}
.dash-title p{font-size:12.5px;color:var(--slate);margin-top:2px;line-height:1.35}
.dash-top-actions{display:flex;align-items:center;gap:10px}
/* padding:0 matters: this is a <button>, and the browser's default button
   padding squeezed the picture inwards, leaving the blue gradient showing down
   the left and right of it. overflow:hidden keeps the corners round. */
.dash-avatar{width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,var(--blue),#7aa0ff);color:#fff;border:0;padding:0;overflow:hidden;font-weight:800;font-size:13px;cursor:pointer;display:flex;align-items:center;justify-content:center}
.dash-content{padding:24px;flex:1;min-width:0}
.dash-overlay{position:fixed;inset:0;background:rgba(6,8,20,.5);opacity:0;visibility:hidden;transition:opacity .2s,visibility .2s;z-index:99}
.dash-overlay.on{opacity:1;visibility:visible}
.dash-note{font-size:13.5px;color:var(--slate);line-height:1.6}
.dash-actions-bar{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:20px}
.dash-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:24px}
.stat{background:#fff;border:1px solid var(--line);border-radius:14px;padding:18px}
.stat-l{font-size:11.5px;font-weight:700;color:var(--slate);text-transform:uppercase;letter-spacing:.06em}
.stat-n{font-size:26px;font-weight:800;font-family:var(--mono);letter-spacing:-.02em;margin-top:7px}
.stat-s{font-size:12px;color:var(--slate-light);margin-top:3px}
.dash-cols{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.dash-card{background:#fff;border:1px solid var(--line);border-radius:16px;padding:20px}
.dash-card h2{font-size:15.5px;font-weight:800;margin-bottom:14px}
/* Flat: the heading and the rows sit on the page rather than inside a panel.
   Used on the overview, where the two lists are the content and a card around
   each one was a frame drawn around things that already have their own shape. */
.dash-card-flat{background:none;border:0;border-radius:0;padding:0}
.dash-list{display:flex;flex-direction:column;gap:12px}
.dash-item{display:flex;align-items:center;gap:15px;background:#fff;border:1px solid var(--line);border-radius:14px;padding:16px;flex-wrap:wrap}
.di-thumb{width:92px;height:62px;border-radius:11px;overflow:hidden;background:var(--blue-tint);flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:24px;border:1px solid var(--line-soft)}
.di-thumb img{width:100%;height:100%;object-fit:cover}
.di-thumb.empty{color:var(--slate-light)}
.di-main{flex:1;min-width:0}
.di-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.di-name{font-weight:700;font-size:14.5px}
.di-tag{font-size:12.5px;color:var(--slate);margin-top:4px}
.di-meta{font-size:12px;color:var(--slate-light);margin-top:6px;font-family:var(--mono)}
.di-warn{margin-top:9px;font-size:12.5px;color:#a26a05;background:#fff8ea;border:1px solid #f5d99b;border-radius:9px;padding:8px 12px;line-height:1.5}
.di-reason{margin-top:9px;font-size:12.5px;color:#b3261e;background:#fdeaea;border:1px solid #f6c9c9;border-radius:9px;padding:8px 12px;line-height:1.5}
.di-actions{display:flex;gap:8px;flex-wrap:wrap}
.di-actions .btn{padding:8px 14px;font-size:12.5px}
.btn-ghost.danger{color:#c8352f}
.btn-ghost.danger:hover{border-color:#f6c9c9;background:#fdeaea}
.dash-table{width:100%;border-collapse:collapse;font-size:13px;min-width:620px}
.table-scroll{overflow-x:auto}
.dash-table th{text-align:left;font-size:11px;font-weight:700;color:var(--slate);text-transform:uppercase;letter-spacing:.06em;padding:11px 14px;background:var(--blue-tint);border-bottom:1px solid var(--line)}
.dash-table td{padding:12px 14px;border-bottom:1px solid var(--line-soft);vertical-align:middle}
.dash-table tr:last-child td{border-bottom:none}
.dash-form{display:flex;flex-direction:column;gap:15px}
/* Not scoped to .dash-form: the same label marker is used on settings cards and
   the item form, which are not always inside one. */
.opt{font-weight:500;color:var(--slate-light);font-size:11px}
.dash-check{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--ink-soft);cursor:pointer;padding:4px 0}
.dash-check input{accent-color:var(--blue);width:16px;height:16px}
.dash-visit{padding:8px 14px;font-size:12.5px}
/* Slide-over drawer */
.drawer-overlay{position:fixed;inset:0;background:rgba(6,8,20,.5);opacity:0;visibility:hidden;transition:opacity .2s,visibility .2s;z-index:130}
.drawer-overlay.on{opacity:1;visibility:visible}
.drawer{position:fixed;top:0;right:0;height:100vh;width:min(520px,100vw);background:#fff;z-index:140;transform:translateX(100%);transition:transform .24s ease;display:flex;flex-direction:column;box-shadow:-8px 0 40px rgba(0,0,0,.16)}
.drawer.on{transform:none}
.drawer-head{display:flex;align-items:center;justify-content:space-between;padding:18px 24px;border-bottom:1px solid var(--line)}
.drawer-head h2{font-size:17px;font-weight:800}
.drawer-body{flex:1;overflow-y:auto;padding:20px 24px}
.drawer-sec{font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--slate);margin:22px 0 10px;padding-top:16px;border-top:1px solid var(--line-soft)}
.drawer-body>.drawer-sec:first-child{margin-top:0;padding-top:0;border-top:none}
.drawer-foot{display:flex;gap:10px;justify-content:flex-end;padding:16px 24px calc(16px + env(safe-area-inset-bottom));border-top:1px solid var(--line);background:var(--blue-tint)}
/* product media in the list */
.md-for{font-size:13px;color:var(--slate);margin-bottom:6px}
.md-thumb-row{display:flex;gap:16px;align-items:flex-start;margin-top:12px;flex-wrap:wrap}
.md-thumb{width:180px;height:112px;border-radius:12px;background:var(--blue-tint);border:1px dashed var(--line);display:flex;align-items:center;justify-content:center;overflow:hidden;flex-shrink:0;color:var(--slate-light);font-size:12.5px}
.md-thumb img{width:100%;height:100%;object-fit:cover}
.md-gallery{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:12px}
.md-gal-item{position:relative;aspect-ratio:16/10;border-radius:10px;overflow:hidden;border:1px solid var(--line)}
.md-gal-item img{width:100%;height:100%;object-fit:cover}
.md-gal-x{position:absolute;top:5px;right:5px;width:24px;height:24px;border-radius:50%;background:rgba(0,0,0,.6);color:#fff;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer}
.md-gal-x:hover{background:#c8352f}
.md-gal-empty{grid-column:1/-1;font-size:13px;color:var(--slate-light);padding:16px;text-align:center;background:var(--blue-tint);border-radius:10px}
.md-pkg{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-top:12px;padding:15px;border:1px dashed var(--line);border-radius:12px;flex-wrap:wrap}
.md-pkg.has{border-style:solid;border-color:#b8ead6;background:var(--green-wash)}
.md-pkg-state{display:flex;align-items:center;gap:10px;font-size:13.5px;font-weight:600;color:var(--slate)}
.md-pkg.has .md-pkg-state{color:#0a7a56}
.md-progress{height:6px;background:var(--line-soft);border-radius:20px;overflow:hidden;margin-top:12px}
.md-bar{height:100%;width:0;background:var(--blue);border-radius:20px;transition:width .15s ease}
/* API keys */
.key-explain{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:20px}
.key-card{background:#fff;border:1px solid var(--line);border-radius:14px;padding:18px}
.key-card h3{font-size:14px;font-weight:800;margin-bottom:7px}
.key-card p{font-size:12.5px;color:var(--slate);line-height:1.55}
.key-value{display:flex;align-items:center;gap:10px;background:var(--blue-tint);border:1px solid var(--line-soft);border-radius:10px;padding:11px 13px;margin-top:10px;flex-wrap:wrap}
.key-value code{font-family:var(--mono);font-size:12.5px;font-weight:700;word-break:break-all;flex:1;min-width:0}
.key-once{background:#fff8ea;border:1px solid #f5d99b;border-radius:12px;padding:16px;margin-bottom:18px}
.key-once h3{font-size:14px;font-weight:800;color:#a26a05;margin-bottom:6px}
/* Apply / gate states */
.apply-wrap{max-width:640px;margin:0 auto}
.apply-state{background:#fff;border:1px solid var(--line);border-radius:18px;padding:32px;text-align:center}
.apply-ic{width:64px;height:64px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 18px;background:var(--blue-wash);color:var(--blue)}
.apply-ic.ok{background:var(--green-wash);color:#0a7a56}
.apply-ic.wait{background:#fff5e5;color:#a26a05}
.apply-ic.bad{background:#fdeaea;color:#c8352f}
.apply-state h2{font-size:21px;font-weight:800;margin-bottom:9px}
.apply-state p{color:var(--slate);font-size:14.5px;line-height:1.65;max-width:420px;margin:0 auto}
@media(max-width:1000px){.dash-stats{grid-template-columns:1fr 1fr}.dash-cols{grid-template-columns:1fr}.key-explain{grid-template-columns:1fr}}
@media(max-width:900px){
  .dash-side{position:fixed;left:0;top:0;z-index:100;transform:translateX(-100%);transition:transform .2s ease;width:255px;padding:18px 14px}
  .dash-side.on{transform:none}
  .dash-side-close{display:flex}
  .dash-burger{display:flex}
  .dash-top{padding:12px 18px}
  .dash-content{padding:18px}
}
@media(max-width:560px){
  .dash-stats{grid-template-columns:1fr}
  .di-actions{width:100%}
  .di-actions .btn{flex:1;justify-content:center}
  .md-gallery{grid-template-columns:1fr 1fr}
  .di-thumb{width:100%;height:120px}
  .dash-visit{display:none}
}

/* ============ API & SDK docs ============ */
/* ============ API documentation ============ */
/* Its own shell: a fixed contents rail and a reading column. The storefront
   header and category row would push the reference down the page and compete
   with the sidebar, which is the navigation that matters here. */
.html-docs,.docs-body{min-height:100%}
.docs-body{background:#fff}
.dx{display:flex;min-height:100vh}

/* Contents rail */
.dx-side{position:sticky;top:0;align-self:flex-start;flex-shrink:0;width:284px;height:100vh;
  overflow-y:auto;background:var(--blue-tint);border-right:1px solid var(--line);
  padding:24px 16px 28px;display:flex;flex-direction:column;gap:4px}
.dx-brand{display:flex;align-items:center;gap:9px;padding:0 8px}
/* The logo is the flexible one and the badge holds its size: the other way round
   the badge wrapped to two lines as soon as the lockup wanted the width. */
.dx-logo{display:flex;align-items:center;min-width:0;flex:0 1 auto}
/* The mark is drawn white for the dark header; on this pale rail it inverts. */
.dx-logo .logo-img{height:28px;width:auto;max-width:100%;display:block;filter:invert(1) hue-rotate(180deg)}
.dx-ver{flex-shrink:0;white-space:nowrap;font-family:var(--mono);font-size:10px;font-weight:700;
  letter-spacing:.03em;color:var(--blue-deep);background:var(--blue-wash);border:1px solid #cfdcff;
  border-radius:20px;padding:3px 8px}
.dx-caption{font-size:12px;color:var(--slate);padding:0 8px;margin:8px 0 18px}
.dx-nav{display:flex;flex-direction:column;gap:1px;flex:1}
.dx-group{font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--slate-light);padding:18px 8px 7px}
.dx-group:first-child{padding-top:0}
.dx-link{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:9px;
  font-size:13.5px;font-weight:600;color:var(--slate)}
.dx-link:hover{background:rgba(255,255,255,.75);color:var(--ink)}
.dx-link.on{background:#fff;color:var(--blue);box-shadow:0 1px 3px rgba(10,17,48,.07)}
.dx-verb{font-family:var(--mono);font-size:9px;font-weight:700;letter-spacing:.04em;
  padding:2px 6px;border-radius:4px;flex-shrink:0;width:38px;text-align:center}
.dx-verb.get{background:var(--green-wash);color:#0a7a56}
.dx-verb.post{background:#fdf0e3;color:#a26a05}
.dx-side-foot{display:flex;flex-direction:column;gap:8px;padding:20px 8px 0;
  margin-top:16px;border-top:1px solid var(--line)}
.dx-side-foot .btn{justify-content:center;font-size:13px;padding:10px 14px}
.dx-back{font-size:12px;font-weight:600;color:var(--slate);text-align:center;margin-top:4px}
.dx-back:hover{color:var(--blue)}

/* Reading column */
.dx-main{flex:1;min-width:0}
.dx-in{max-width:860px;padding:56px 48px 90px}
.dx-in h1{font-size:38px;font-weight:800;letter-spacing:-.035em;margin-bottom:14px;scroll-margin-top:24px}
.dx-lead{font-size:16.5px;line-height:1.7;color:var(--slate);max-width:62ch;margin-bottom:22px}
.dx-meta{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:26px}
.dx-meta span{font-size:12.5px;color:var(--slate);background:#fff;border:1px solid var(--line);
  border-radius:20px;padding:7px 14px}
.dx-meta b{color:var(--ink);font-weight:700;margin-right:5px}
.dx-meta code{font-family:var(--mono);font-size:12px;color:var(--blue-deep)}

.dx-sec{margin-top:52px}
.dx-sec h2{font-size:25px;font-weight:800;letter-spacing:-.025em;margin-bottom:12px;scroll-margin-top:24px}
.dx-sec h3{font-size:14.5px;font-weight:800;margin-bottom:5px}
.dx-sec p{font-size:15px;line-height:1.75;color:var(--ink-soft);margin-bottom:14px}
.dx-sub{font-size:13.5px !important;color:var(--slate) !important}
.dx-err{font-size:13px !important;color:var(--slate) !important;margin:0 !important}
.dx-sec a:not(.btn){color:var(--blue);font-weight:600}
.dx-sec a:not(.btn):hover{text-decoration:underline}
.dx-in code{font-family:var(--mono);font-size:13px;background:var(--blue-tint);
  border:1px solid var(--line-soft);padding:2px 6px;border-radius:6px;color:var(--blue-deep);white-space:nowrap}
.dx-steps{margin:0 0 18px;padding-left:20px;display:flex;flex-direction:column;gap:10px;list-style:decimal}
.dx-list{margin:0 0 18px;padding-left:20px;display:flex;flex-direction:column;gap:9px;list-style:disc}
.dx-steps li,.dx-list li{font-size:15px;line-height:1.75;color:var(--ink-soft)}
.dx-note{background:var(--blue-tint);border:1px solid var(--line);border-left:3px solid var(--blue);
  border-radius:12px;padding:15px 18px;font-size:14px;line-height:1.7;color:var(--ink-soft)}
.dx-callout{display:flex;gap:11px;align-items:flex-start;background:var(--green-wash);
  border:1px solid #cfe8dc;border-radius:12px;padding:14px 16px;margin-bottom:16px;
  font-size:13.5px;line-height:1.7;color:#14503a}
.dx-callout svg{flex-shrink:0;margin-top:2px;color:#0a7a56}

/* Code blocks */
.dcode{background:#0f1424;border-radius:13px;overflow:hidden;margin-bottom:18px}
.dcode-bar{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:9px 13px;background:rgba(255,255,255,.05);border-bottom:1px solid rgba(255,255,255,.08)}
.dcode-bar span{font-family:var(--mono);font-size:10.5px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:rgba(255,255,255,.5)}
.dcode-copy{border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.08);color:#fff;
  font:inherit;font-size:11.5px;font-weight:600;padding:4px 11px;border-radius:7px;cursor:pointer}
.dcode-copy:hover{background:rgba(255,255,255,.2)}
.dcode pre{margin:0;padding:15px 16px;overflow-x:auto}
.dcode code{font-family:var(--mono);font-size:12.5px;line-height:1.75;color:#dbe2f5;
  background:none;border:0;padding:0;white-space:pre}

/* Keys and endpoints */
.dx-keys{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:18px}
.dx-key{display:flex;gap:13px;align-items:flex-start;background:#fff;border:1px solid var(--line);
  border-radius:14px;padding:16px}
.dx-key p{font-size:13px;margin:6px 0 0;line-height:1.65}
.dx-key h3 code{font-size:11.5px;font-weight:600}
.dx-ep{border:1px solid var(--line);border-radius:16px;padding:20px;margin-bottom:16px;
  background:#fff;scroll-margin-top:24px}
.dx-ep-head{display:flex;align-items:center;gap:10px;margin-bottom:10px;flex-wrap:wrap}
.dx-ep-head code{background:none;border:0;font-size:14.5px;font-weight:700;color:var(--ink);padding:0}
.dx-ep-cols{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.dx-ep-cols>*{min-width:0}
.dx-ep p:last-child{margin-bottom:0}

.dx-cta{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap;
  background:linear-gradient(150deg,#0b0b0e,#12206b);color:#fff;border-radius:18px;padding:28px;margin-top:56px}
.dx-cta h3{font-size:19px;font-weight:800}
.dx-cta p{color:rgba(255,255,255,.72);margin:6px 0 0;font-size:14.5px}

/* Contents as an off-canvas panel on narrow screens */
.dx-open{display:none;align-items:center;gap:9px;position:fixed;left:14px;bottom:14px;z-index:60;
  background:var(--ink);color:#fff;border:0;border-radius:30px;padding:12px 18px;
  font:inherit;font-size:13px;font-weight:700;cursor:pointer;box-shadow:var(--shadow-lg)}
.dx-overlay{display:none;position:fixed;inset:0;background:rgba(6,8,20,.5);z-index:70}
.dx-overlay.on{display:block}

@media(max-width:1000px){
  .dx-in{padding:40px 26px 110px}
  .dx-ep-cols,.dx-keys{grid-template-columns:1fr}
  .dx-open{display:inline-flex}
  .dx-side{position:fixed;top:0;left:0;z-index:80;transform:translateX(-100%);
    transition:transform .22s ease;width:290px;box-shadow:var(--shadow-lg)}
  .dx-side.on{transform:none}
}
@media(max-width:560px){
  .dx-in{padding:30px 18px 110px}
  .dx-in h1{font-size:30px}
  .dx-sec h2{font-size:21px}
  .dx-lead{font-size:15px}
}



/* ============ Mobile menu + account panel ============ */
/* Account panel slides in from the right, so it reads as belonging to the
   avatar on that side rather than to the hamburger on the left. */
.m-menu.m-right{left:auto;right:0;transform:translateX(100%)}
.m-menu.m-right.on{transform:none}
.m-head-title{font-weight:800;font-size:16px;color:var(--ink)}
.m-sec{font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--slate-light);padding:12px 12px 5px}
.m-sec:first-child{padding-top:4px}
.m-links .m-free{color:var(--green)}
.m-links .m-free .mi{color:var(--green)}
/* The cross-sell to domzivo.com carries the longest label in the menu. It is a
   secondary promo, so it takes a smaller size and stays on one line at any
   width, truncating rather than wrapping if a device is narrower still. */
.m-links .m-cross{font-size:12.5px;padding:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--slate);margin-top:4px;border-top:1px solid var(--line-soft);border-radius:0}
.m-links .m-cross:hover,.m-links .m-cross:active{background:var(--blue-tint);color:var(--blue)}
.m-acct-body{padding:14px 14px calc(14px + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:9px;overflow-y:auto}
.m-acct-note{font-size:13px;color:var(--slate);line-height:1.55;margin:2px 4px 6px}
.m-wide{width:100%;justify-content:center}
.m-acct-sep{height:1px;background:var(--line);margin:5px 0}
.m-links-row{display:flex;align-items:center;gap:12px;padding:13px 14px;border-radius:11px;font-weight:600;font-size:15px;color:var(--ink)}
.m-links-row:hover,.m-links-row:active{background:var(--blue-tint);color:var(--blue)}
.m-links-row.danger{color:#c8352f}
.m-links-row.danger:hover{background:#fdeaea}
.m-links-row .mi{width:22px;display:flex;align-items:center;justify-content:center;color:var(--slate);flex-shrink:0}
.m-links-row:hover .mi,.m-links-row:active .mi{color:var(--blue)}
.m-links-row.danger .mi{color:#c8352f}
.m-guest-btns{display:flex;flex-direction:column;gap:10px}

/* ============ Confirm modal (dashboard) ============ */
/* The platform's own dialog, never a browser confirm(). */
/* The dialog markup is .modal-wrap > (.modal-back + .modal): the backdrop and
   the panel are SIBLINGS. These rules were written as though .modal sat inside
   .modal-back, and .modal-wrap had no rules at all, so the panel was never
   positioned by anything. Appended to <body class="dash-body">, which is
   display:flex, it became a plain flex item after the main column and landed in
   the top right corner with the page dimmed behind it.
   The wrap is now the fixed centring layer, the backdrop fills it, and the
   panel sits above the backdrop. */
.modal-wrap{position:fixed;inset:0;z-index:240;display:flex;align-items:center;justify-content:center;
  padding:20px;opacity:0;transition:opacity .16s ease}
.modal-wrap.on{opacity:1}
.modal-back{position:absolute;inset:0;background:rgba(6,8,20,.6)}
.modal{position:relative;background:#fff;border-radius:18px;max-width:420px;width:100%;padding:26px;
  box-shadow:0 24px 70px rgba(0,0,0,.35);max-height:calc(100vh - 40px);overflow-y:auto;
  transform:translateY(8px) scale(.985);transition:transform .16s ease}
.modal-wrap.on .modal{transform:none}
@media(prefers-reduced-motion:reduce){
  .modal-wrap,.modal{transition:none}
}
.modal h3{font-size:18px;font-weight:800;margin-bottom:9px}
.modal p{font-size:14px;color:var(--slate);line-height:1.6}
.modal .auth-input{margin-top:14px}
.modal-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:20px;flex-wrap:wrap}

/* ============ Dashboard extras ============ */
.dash-card-head{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-bottom:14px;flex-wrap:wrap}
.dash-card-head h2{margin-bottom:0}
.dash-card-lg{background:#fff;border:1px solid var(--line);border-radius:18px;padding:26px}
.dash-grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.dash-empty{padding:26px;text-align:center;font-size:13.5px;color:var(--slate);background:var(--blue-tint);border-radius:12px}
/* Inside a flat section the empty state is the one thing that gets a surface.
   The dashboard page is itself tinted, so the tint it normally uses would be
   invisible here: white, and the line of text reads as a panel saying there is
   nothing yet rather than as text nobody finished. */
.dash-card-flat .dash-empty{background:#fff;border:1px solid var(--line)}
.dash-rows{display:flex;flex-direction:column}
.dash-row{display:flex;align-items:center;gap:14px;padding:12px 0;border-bottom:1px solid var(--line-soft)}
.dash-row:last-child{border-bottom:none}
/* The rows stay on the page. Their divider steps up from line-soft to line,
   which is nearly invisible against the dashboard's tint. */
.dash-card-flat .dash-row{border-bottom-color:var(--line);padding:13px 0}
.dr-name{font-weight:600;font-size:13.5px;flex:1;min-width:0}
.dr-meta{font-size:12px;color:var(--slate);margin-top:3px}
.dr-val{font-family:var(--mono);font-weight:800;font-size:14px;flex-shrink:0}
.stat-sub{font-size:11.5px;color:var(--slate-light);margin-top:4px}
.di-code{font-family:var(--mono);font-size:12.5px;font-weight:700;color:var(--ink);background:var(--blue-tint);padding:3px 8px;border-radius:6px;display:inline-block}
.ta-r{text-align:right}
.td-name{font-weight:600;color:var(--ink)}
.earn{color:#0a7a56;font-weight:700}
.muted{color:var(--slate-light)}
.dash-status{display:flex;align-items:flex-start;gap:15px;padding:18px;border-radius:14px;background:var(--blue-tint);border:1px solid var(--line);margin-bottom:20px}
.dash-status-ic{width:42px;height:42px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;background:#fff}
.dash-status-reason{font-size:13px;color:#b3261e;background:#fdeaea;border:1px solid #f6c9c9;border-radius:9px;padding:9px 12px;margin-top:10px;line-height:1.55}
@media(max-width:900px){.dash-grid-3{grid-template-columns:1fr}}

/* ============ Product form (its own page) ============ */
/* Wider than 1100 now that the sidebar carries the classifying panels: at the
   old width the two columns fought for room once media moved across. */
.pf-page{max-width:1240px}
.pf-grid{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:20px;align-items:start}
.pf-main{display:flex;flex-direction:column;gap:18px;min-width:0}
/* Not sticky any more: the sidebar is taller than the viewport now that it
   holds category, tags, both image panels and the package, and a sticky column
   longer than the screen simply cannot be scrolled to the bottom of. */
.pf-side{display:flex;flex-direction:column;gap:14px;min-width:0}
.pf-actions{display:flex;flex-direction:column;gap:10px}
.pf-title-input{font-size:16px;font-weight:600}

/* ── Product data: tabbed settings ───────────────────────────
   Vertical tabs beside the panel on a wide screen, a scrolling strip above it
   on a narrow one. */
.pf-data-body{display:grid;grid-template-columns:190px minmax(0,1fr);gap:0;margin-top:14px;
  border:1px solid var(--line);border-radius:12px;overflow:hidden}
.pf-dtabs{display:flex;flex-direction:column;background:var(--blue-tint);border-right:1px solid var(--line)}
.pf-dtab{appearance:none;background:none;border:0;border-left:3px solid transparent;text-align:left;
  padding:12px 16px;font:600 13.5px var(--sans);color:var(--slate);cursor:pointer;white-space:nowrap;
  transition:color .12s,background .12s,border-color .12s}
.pf-dtab:hover{color:var(--ink);background:rgba(255,255,255,.6)}
.pf-dtab.on{color:var(--blue);background:#fff;border-left-color:var(--blue)}
.pf-dtab:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
.pf-dpanels{background:#fff;min-width:0}
.pf-dpanel{padding:18px}

/* The panel scrolls inside itself rather than stretching the page.
   Details holds four blocks, so opening it used to push the box past the
   viewport: the tab column scrolled away with it and there was no way to
   reach another tab without scrolling back up. Capped here, the box stays a
   fixed size, the tabs stay beside it, and long panels scroll on their own.
   Only from 701px up, where the tabs sit alongside; on a phone they are a
   strip above the panel and a scroll box inside a scrolling page is worse
   than a long panel. */
@media(min-width:701px){
  .pf-dpanels{max-height:min(64vh,620px);overflow-y:auto;scroll-padding-block:18px}
  /* The tab column deliberately keeps stretching to the row height. Making it
     sticky needs align-self:start, which stops it filling the row and leaves
     its tint and right border ending halfway down. It earns nothing anyway:
     the box is now capped to fit the screen, so the tabs are already in view. */
  .pf-dpanels::-webkit-scrollbar{width:10px}
  .pf-dpanels::-webkit-scrollbar-track{background:transparent}
  .pf-dpanels::-webkit-scrollbar-thumb{background:#d9dce5;border-radius:20px;
    border:3px solid #fff}
  .pf-dpanels::-webkit-scrollbar-thumb:hover{background:#c3c7d4}
  .pf-dpanels{scrollbar-width:thin;scrollbar-color:#d9dce5 transparent}
}

/* A panel with several distinct settings in it, separated rather than run
   together as one column of inputs. */
.pf-block + .pf-block{margin-top:22px;padding-top:20px;border-top:1px solid var(--line-soft)}
.pf-block h3,.pf-sub h3{font-size:13px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;
  color:var(--slate);margin:0 0 8px}
.pf-two{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:20px;margin-top:14px}
.pf-sub{min-width:0}
.pf-shots-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px}

/* ── Sidebar metaboxes ───────────────────────────────────────
   <details> rather than a scripted toggle: the open state, the keyboard
   behaviour and the screen-reader semantics all come for free, and the panel
   still opens if the script never loads. */
.pf-box{background:#fff;border:1px solid var(--line);border-radius:14px;overflow:hidden}
.pf-box > summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:10px;
  padding:13px 15px;font-size:14.5px;font-weight:800;color:var(--ink);user-select:none}
.pf-box > summary::-webkit-details-marker{display:none}
.pf-box > summary::after{content:"";margin-left:auto;flex-shrink:0;width:8px;height:8px;
  border-right:2px solid var(--slate-light);border-bottom:2px solid var(--slate-light);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .18s ease}
.pf-box[open] > summary::after{transform:rotate(-135deg) translate(-2px,-2px)}
.pf-box > summary:hover{background:var(--blue-tint)}
.pf-box > summary:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
.pf-box[open] > summary{border-bottom:1px solid var(--line-soft)}
.pf-box-body{padding:14px 15px 15px}

/* The item id, sized to be copied rather than read. It wraps, because a uuid
   is wider than this sidebar and truncating the one value a seller must get
   exactly right would be the wrong trade. */
.pf-idrow{display:flex;align-items:stretch;gap:8px;margin:10px 0}
.pf-id{flex:1;min-width:0;font-family:var(--mono);font-size:11.5px;line-height:1.5;
  color:var(--ink);background:var(--blue-tint);border:1px solid var(--line);
  border-radius:9px;padding:8px 10px;word-break:break-all;user-select:all}
.pf-id-copy{flex-shrink:0;align-self:flex-start;font-size:12px;padding:8px 12px}
.pf-box-body > .dash-note:first-child{margin-top:0}
@media(prefers-reduced-motion:reduce){.pf-box > summary::after{transition:none}}

@media(max-width:1040px){
  .pf-grid{grid-template-columns:1fr}
  /* The save controls are pinned rather than left at the bottom of a stacked
     page: below the fold sat three form cards and five metaboxes, so saving
     meant scrolling past the entire form to find the button. */
  .pf-actions{position:fixed;left:0;right:0;bottom:0;z-index:60;
    flex-direction:row;flex-wrap:wrap;align-items:center;gap:8px;
    border-radius:0;border-left:0;border-right:0;border-bottom:0;padding:10px 14px;
    box-shadow:0 -6px 22px rgba(10,17,48,.12)}
  .pf-actions .btn{flex:1 1 auto;min-width:0;justify-content:center}
  .pf-actions .pf-hint{display:none}
  .pf-actions .pf-status{flex:1 1 100%;margin:0}
  /* Room for the bar, so the last panel is never trapped underneath it. */
  .pf-page{padding-bottom:84px}
}
@media(max-width:700px){
  /* Tabs become a horizontal strip: 190px of labels down the side leaves
     almost nothing for the fields on a phone. */
  .pf-data-body{grid-template-columns:1fr}
  .pf-dtabs{flex-direction:row;overflow-x:auto;border-right:0;border-bottom:1px solid var(--line);
    scrollbar-width:none}
  .pf-dtabs::-webkit-scrollbar{display:none}
  .pf-dtab{flex-shrink:0;border-left:0;border-bottom:3px solid transparent;padding:11px 14px}
  .pf-dtab.on{border-left-color:transparent;border-bottom-color:var(--blue)}
  .pf-dpanel{padding:15px}

  /* Everything below is the phone pass. The page was built for two columns and
     simply stacking it left cards padded like desktop panels and a thumbnail
     row that could not fit its buttons beside the image. */
  .pf-page{max-width:100%}
  .pf-grid{gap:14px}
  .pf-main{gap:14px}
  .pf-side{gap:12px}
  .dash-card{padding:15px}
  .pf-title-input{font-size:15px}
  /* Image over buttons: side by side left the preview about 90px wide. */
  .pf-thumb{flex-direction:column;gap:12px}
  .pf-thumb-side{flex-direction:row;flex-wrap:wrap;align-items:center;width:100%}
  .pf-thumb-side .auth-hint{flex:1 1 100%}
  /* Two up rather than one enormous column of screenshots. */
  .pf-shots{grid-template-columns:repeat(2,1fr)}
  .auth-2col{grid-template-columns:1fr}
  .pf-two{grid-template-columns:1fr;gap:16px}
  .pf-sub + .pf-sub{padding-top:16px;border-top:1px solid var(--line-soft)}
}
.pf-status{font-size:12.5px;color:var(--slate);display:flex;align-items:center;gap:8px;padding-bottom:4px}
.pf-hint{font-size:12px;margin-top:2px}
.pf-media-link{width:100%;justify-content:center}
/* What the seller actually keeps, shown live because the platform fee applies
   to the support add-on too, which is not obvious from the price fields. */
.pf-payout{background:var(--blue-tint);border:1px solid var(--line);border-radius:11px;padding:12px 14px;font-size:12.5px;color:var(--ink-soft);line-height:1.55}
.pf-payout b{color:var(--ink)}

/* ============ Rich text editor ============ */
.rte{border:1px solid var(--line);border-radius:12px;background:#fff;overflow:hidden}
.rte:focus-within{border-color:var(--blue);box-shadow:0 0 0 3px rgba(31,82,255,.1)}
.rte-bar{display:flex;flex-wrap:wrap;gap:2px;padding:7px 8px;border-bottom:1px solid var(--line-soft);background:var(--blue-tint)}
.rte-group{display:flex;gap:2px;padding-right:7px;margin-right:5px;border-right:1px solid var(--line)}
.rte-group:last-child{border-right:0;margin-right:0;padding-right:0}
.rte-btn{min-width:30px;height:30px;padding:0 7px;border:0;background:none;border-radius:7px;color:var(--slate);
  cursor:pointer;display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:700}
.rte-btn:hover{background:#fff;color:var(--blue);box-shadow:0 1px 3px rgba(10,17,48,.1)}
.rte-btn.rte-text{font-family:var(--mono);letter-spacing:.02em}
/* Insert panel: sits inside the editor rather than being a browser prompt, so
   a link can carry its own wording and the whole thing matches the app. */
.rte-panel{padding:14px;border-bottom:1px solid var(--line-soft);background:#fff}
.rte-panel-t{font-size:12.5px;font-weight:700;margin-bottom:10px}
.rte-panel-fields{display:flex;flex-direction:column;gap:9px}
.rte-field{display:flex;flex-direction:column;gap:5px}
.rte-field span{font-size:11.5px;font-weight:600;color:var(--slate)}
.rte-field input{font:inherit;font-size:13.5px;padding:9px 11px;border:1px solid var(--line);border-radius:9px;background:#fff;color:var(--ink)}
.rte-field input:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(31,82,255,.1)}
/* Colour: the button carries a bar of the colour last used, so the toolbar
   shows what a click would apply without having to open the panel. */
.rte-color-btn{position:relative;padding-bottom:5px}
.rte-color-dot{position:absolute;left:7px;right:7px;bottom:4px;height:3px;border-radius:2px}
.rte-swatches{display:flex;flex-wrap:wrap;gap:8px}
.rte-swatch{width:30px;height:30px;border-radius:8px;border:1px solid rgba(10,17,48,.14);cursor:pointer;padding:0}
.rte-swatch:hover{transform:scale(1.08);box-shadow:0 2px 8px rgba(10,17,48,.18)}
.rte-swatch:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
/* An image still on its way to the server, shown from the local file. */
.rte-area img.rte-uploading{opacity:.5;filter:saturate(.4)}
.rte-panel-err{margin-top:9px;font-size:12px;color:#b3261e;background:#fdeaea;border:1px solid #f6c9c9;border-radius:8px;padding:8px 11px}
.rte-panel-actions{display:flex;gap:8px;margin-top:11px}
@media(min-width:560px){
  .rte-panel-fields{flex-direction:row}
  .rte-field{flex:1;min-width:0}
}

/* The editing surface reuses the form input look, minus its border. */
.rte-area{border:0!important;border-radius:0!important;box-shadow:none!important;min-height:220px;max-height:520px;
  overflow-y:auto;padding:16px!important;font-size:14.5px;line-height:1.7;color:var(--ink)}
.rte-area:focus{outline:none}
.rte-area.is-empty::before{content:attr(data-placeholder);color:#a9adbb;pointer-events:none}
.rte-foot{padding:8px 14px;border-top:1px solid var(--line-soft);font-size:11.5px;color:var(--slate-light);background:var(--blue-tint)}
.rte-short{color:#a26a05;font-weight:600}
/* Shared by the editor and the rendered description, so a seller sees on the
   item page exactly what they laid out here. */
.rte-area h2,.rte-content h2{font-size:20px;font-weight:800;margin:20px 0 10px;letter-spacing:-.02em}
.rte-area h3,.rte-content h3{font-size:17px;font-weight:700;margin:18px 0 8px}
.rte-area h4,.rte-content h4{font-size:15px;font-weight:700;margin:16px 0 6px}
.rte-area h2:first-child,.rte-content h2:first-child,
.rte-area h3:first-child,.rte-content h3:first-child{margin-top:0}
.rte-area p,.rte-content p{margin:0 0 13px}
.rte-area p:last-child,.rte-content p:last-child{margin-bottom:0}
.rte-area ul,.rte-content ul,.rte-area ol,.rte-content ol{margin:0 0 14px;padding-left:22px}
.rte-area li,.rte-content li{margin-bottom:6px;line-height:1.65}
.rte-area a,.rte-content a{color:var(--blue);font-weight:600}
.rte-area a:hover,.rte-content a:hover{text-decoration:underline}
.rte-area img,.rte-content img{max-width:100%;height:auto;border-radius:10px;margin:8px 0;display:block}
.rte-area blockquote,.rte-content blockquote{margin:0 0 14px;padding:12px 16px;border-left:3px solid var(--blue);
  background:var(--blue-tint);border-radius:0 10px 10px 0;color:var(--ink-soft)}
.rte-area pre,.rte-content pre{background:var(--ink);color:#e6e9f2;border-radius:10px;padding:14px 16px;
  overflow-x:auto;margin:0 0 14px;font-family:var(--mono);font-size:13px;line-height:1.6;min-width:0;max-width:100%}
.rte-area code,.rte-content code{font-family:var(--mono);font-size:13px}
.rte-area pre code,.rte-content pre code{background:none;padding:0;color:inherit;white-space:pre}
.rte-content code{background:var(--blue-tint);border:1px solid var(--line-soft);padding:1px 6px;border-radius:5px;color:var(--blue-deep)}
.rte-area hr,.rte-content hr{border:0;border-top:1px solid var(--line);margin:18px 0}
.rte-area table,.rte-content table{width:100%;border-collapse:collapse;margin:0 0 14px;font-size:13.5px}
.rte-area th,.rte-content th,.rte-area td,.rte-content td{border:1px solid var(--line);padding:8px 11px;text-align:left}
.rte-area th,.rte-content th{background:var(--blue-tint);font-weight:700}
/* Required marker, the counterpart to .opt */
.req{font-weight:600;color:var(--blue);font-size:11px}

/* Tag input */
.tagbox{display:flex;flex-wrap:wrap;align-items:center;gap:7px;padding:9px 11px;border:1px solid var(--line);border-radius:12px;background:#fff;cursor:text;min-height:46px}
.tagbox:focus-within{border-color:var(--blue);box-shadow:0 0 0 3px rgba(31,82,255,.1)}
.tag-chips{display:contents}
.tag-chip{display:inline-flex;align-items:center;gap:6px;background:var(--blue-wash);color:var(--blue);font-size:12.5px;font-weight:600;padding:5px 6px 5px 11px;border-radius:20px;white-space:nowrap}
.tag-chip button{border:0;background:none;color:inherit;cursor:pointer;font-size:15px;line-height:1;opacity:.6;padding:0 3px}
.tag-chip button:hover{opacity:1}
.tag-input{flex:1;min-width:150px;border:0;outline:0;font:inherit;font-size:14px;padding:4px 0;background:transparent;color:var(--ink)}
.tag-input:disabled{cursor:not-allowed}
/* tags on the product list */
.di-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.di-tag{font-size:11px;font-weight:600;color:var(--slate);background:var(--blue-tint);border:1px solid var(--line-soft);padding:3px 9px;border-radius:20px}
.di-tag.more{color:var(--blue)}
.di-tag-line{font-size:12.5px;color:var(--slate);margin-top:4px}
@media(max-width:1000px){
  .pf-grid{grid-template-columns:1fr}
  .pf-side{position:static;order:-1}
}

/* ============ API keys ============ */
.key-kind{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:3px 9px;border-radius:20px}
.key-kind.pub{background:var(--green-wash);color:#0a7a56}
.key-kind.sec{background:var(--blue-wash);color:var(--blue)}
.key-actions{display:flex;gap:8px;flex-wrap:wrap}
.key-reveal{background:#fff8ea;border:1px solid #f5d99b;border-radius:14px;padding:18px;margin-bottom:18px}
.key-reveal-head{display:flex;align-items:center;gap:9px;font-size:14px;font-weight:800;color:#a26a05;margin-bottom:9px}
.key-reveal-body{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--line);border-radius:10px;padding:12px 14px;flex-wrap:wrap}
.key-reveal-body code{font-family:var(--mono);font-size:12.5px;font-weight:700;word-break:break-all;flex:1;min-width:0}

/* ============ Store settings ============ */
/* Identity and the commission split, side by side above the forms. */
.set-hero{display:flex;align-items:center;justify-content:space-between;gap:22px;flex-wrap:wrap;
  background:var(--ink);color:#fff;border-radius:18px;padding:22px 24px;margin-bottom:30px}
.set-hero-id{display:flex;align-items:center;gap:15px;min-width:0}
.set-avatar{width:52px;height:52px;flex-shrink:0;border-radius:15px;background:var(--blue);
  display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:800;color:#fff}
.set-hero-t{min-width:0}
.set-hero-t h2{font-size:19px;font-weight:800;letter-spacing:-.02em;margin:0 0 3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.set-hero-t a{font-size:12.5px;color:#9fb4ff;font-weight:600}
.set-hero-t a:hover{color:#fff}
.set-split{min-width:200px}
/* The bar reads as the split itself, so the percentage is not doing all the work. */
.set-split-bar{height:7px;border-radius:20px;background:rgba(255,255,255,.16);overflow:hidden;margin-bottom:9px}
.set-split-bar span{display:block;height:100%;background:var(--blue);border-radius:20px;width:0;transition:width .4s ease}
.set-split-t{font-size:12.5px;color:rgba(255,255,255,.62)}
.set-split-t b{color:#fff;font-weight:700}

/* Storefront sections carry 52px of vertical padding; a settings block is not
   one of those, so the element default is cleared rather than worked around. */
/* scroll-margin so an anchored section lands below the sticky navbar rather
   than under it, which is the usual way a working #hash still looks broken. */
.set-sec{padding:0;margin-bottom:34px;scroll-margin-top:calc(var(--nav-h) + 20px)}
/* Arrived from a link that named this section. A short wash, so it is obvious
   which of eight sections was meant without anything staying highlighted. */
.set-sec.is-target .set-sec-head h3,.set-sec.is-target .set-sec-head h2{color:var(--blue)}
.set-sec.is-target .set-card{animation:setflash 1.6s ease-out}
@keyframes setflash{
  0%{box-shadow:0 0 0 3px var(--blue-wash),0 0 0 4px #c6d2ff}
  70%{box-shadow:0 0 0 3px var(--blue-wash),0 0 0 4px #c6d2ff}
  100%{box-shadow:0 0 0 3px transparent,0 0 0 4px transparent}
}
@media(prefers-reduced-motion:reduce){.set-sec.is-target .set-card{animation:none}}
.set-sec-head{margin-bottom:14px}
.set-sec-head h3{font-size:15px;font-weight:800;letter-spacing:-.01em;margin:0 0 4px}
.set-sec-head p{font-size:12.5px;color:var(--slate);margin:0}
.set-card{display:flex;flex-direction:column;gap:16px}
/* Single definition. This was declared twice, here and again in the account
   settings block, so which rules survived depended on source order rather than
   on intent. The two are merged and the duplicate is gone. */
.set-actions{display:flex;gap:9px;flex-wrap:wrap;justify-content:flex-end;
  margin-top:20px;padding-top:18px;border-top:1px solid var(--line-soft)}
.set-actions .btn{min-width:150px;justify-content:center}

/* A destination is collapsed to one line until you need to edit it, so the list
   answers "what am I set up for" before it asks for anything. */
.dest-list{display:flex;flex-direction:column;gap:11px}
.dest{background:#fff;border:1px solid var(--line);border-radius:14px;overflow:hidden;transition:border-color .15s}
.dest.is-ready{border-color:#cfe3d8}
.dest-head{display:flex;align-items:center;gap:14px;width:100%;padding:15px 17px;
  background:none;border:0;text-align:left;font:inherit;color:inherit;cursor:pointer}
.dest-head.as-row{cursor:default}
.dest-head:hover:not(.as-row){background:var(--blue-tint)}
.dest-icon{width:38px;height:38px;flex-shrink:0;border-radius:11px;display:flex;align-items:center;justify-content:center;
  font-size:10px;font-weight:800;letter-spacing:.02em}
.i-bank{background:var(--blue-wash);color:var(--blue-deep)}
.i-trc{background:#fdecec;color:#c8352f}
.i-bep{background:#fdf4dd;color:#8a6b06}
.i-wallet{background:#eceef4;color:var(--ink)}
.dest-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.dest-name{font-size:13.5px;font-weight:700}
.dest-net{font-family:var(--mono);font-size:10.5px;font-weight:700;color:var(--slate);
  background:var(--blue-tint);border:1px solid var(--line);border-radius:5px;padding:1px 5px;vertical-align:1px}
.dest-sub{font-size:12px;color:var(--slate);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dest-state{flex-shrink:0;font-size:11px;font-weight:700;color:var(--slate);background:var(--blue-tint);
  border:1px solid var(--line);border-radius:20px;padding:4px 10px;font-family:var(--mono)}
.dest-state.on{color:#0a7048;background:var(--green-wash);border-color:#bfe6d5}
.dest-chev{flex-shrink:0;color:var(--slate-light);transition:transform .2s}
[aria-expanded="true"] .dest-chev{transform:rotate(180deg)}
.dest-body{display:flex;flex-direction:column;gap:16px;padding:4px 17px 18px;border-top:1px solid var(--line-soft)}
.dest-note{font-size:12px;color:var(--slate);line-height:1.6;margin:14px 0 0}
.dest-note.warn{color:#8a6b06;background:#fdf4dd;border:1px solid #f2e3b4;border-radius:10px;padding:10px 13px}
.auth-input.mono{font-family:var(--mono);font-size:12.5px}

/* A hero that counts things rather than showing a split. */
.av-key{background:var(--blue-deep)}
.hero-counts{display:flex;gap:26px}
.hero-count{display:flex;flex-direction:column;gap:2px}
.hero-count b{font-family:var(--mono);font-size:23px;font-weight:800;letter-spacing:-.02em}
.hero-count span{font-size:11px;color:rgba(255,255,255,.55)}

/* ============ API keys ============ */
/* Built from the destination card, so this page and store settings read alike. */
.i-pub{background:var(--blue-wash);color:var(--blue-deep)}
.i-sec{background:#fdecec;color:#c8352f}
.dest-note.as-body{margin:0;padding:0 17px 16px 69px}
.dest-note.as-body.warn{margin:0 17px 16px 69px;padding:10px 13px}
.akey-body{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:12px 17px 14px 69px;border-top:1px solid var(--line-soft)}
.akey-code{flex:1;min-width:200px;font-family:var(--mono);font-size:12.5px;font-weight:700;
  color:var(--blue-deep);background:var(--blue-tint);border:1px solid var(--line-soft);
  border-radius:9px;padding:9px 12px;word-break:break-all}
.akey-actions{display:flex;gap:7px;flex-shrink:0}
/* A revoked key stays listed as a record, but reads as inactive. */
.ak-revoked-bar{display:flex;justify-content:center;margin-top:14px}
.ak-none-live{font-size:13.5px;color:var(--slate);line-height:1.6;margin:0;padding:16px 0;text-align:center}
.akey.is-revoked{opacity:.6}
.akey.is-revoked .akey-code{color:var(--slate);background:#f6f7fa}
.ak-head{display:flex;align-items:flex-end;justify-content:space-between;gap:14px;flex-wrap:wrap}
.ak-new{display:flex;gap:8px;flex-wrap:wrap}
#ak-reveal{margin-bottom:14px}

@media(max-width:560px){
  .set-hero{padding:18px}
  .set-split{width:100%}
  .dest-head{gap:11px;padding:13px 14px}
  .dest-sub{display:none}
  .dest-state{font-size:10px;padding:3px 8px}
  .hero-counts{gap:18px}
  .hero-count b{font-size:19px}
  /* The 69px indent lines up with the icon tile, which is too much on a phone. */
  .dest-note.as-body{padding:0 14px 14px}
  .dest-note.as-body.warn{margin:0 14px 14px}
  .akey-body{padding:12px 14px 14px}
  .akey-actions{width:100%}
  .akey-actions .btn{flex:1}
}

/* ============ Withdraw ============ */
.wd-form{margin-top:16px}
.wd-amount{display:flex;align-items:center;gap:0;border:1px solid var(--line);border-radius:11px;background:#fff;overflow:hidden}
.wd-amount:focus-within{border-color:var(--blue);box-shadow:0 0 0 3px rgba(31,82,255,.1)}
.wd-cur{flex-shrink:0;padding:0 13px;font-family:var(--mono);font-size:12px;font-weight:700;color:var(--slate);
  background:var(--blue-tint);align-self:stretch;display:flex;align-items:center;border-right:1px solid var(--line)}
.wd-amount .auth-input{border:0!important;border-radius:0!important;box-shadow:none!important;flex:1;min-width:0;
  font-family:var(--mono);font-size:17px;font-weight:700}
.wd-max{flex-shrink:0;margin-right:6px;padding:6px 11px;border:0;border-radius:8px;background:var(--blue-wash);
  color:var(--blue-deep);font:inherit;font-size:11.5px;font-weight:700;cursor:pointer}
.wd-max:hover{background:var(--blue);color:#fff}

.wd-methods{display:flex;flex-direction:column;gap:9px}
.wd-skel{height:60px;border-radius:12px;background:var(--blue-tint)}
.wd-method{display:flex;align-items:center;gap:12px;padding:12px 14px;border:1px solid var(--line);
  border-radius:12px;cursor:pointer;background:#fff;transition:border-color .15s,background .15s}
.wd-method:hover{border-color:#c9d2ea}
.wd-method.on{border-color:var(--blue);background:var(--blue-tint)}
.wd-method.is-off{opacity:.62;cursor:default}
.wd-method.is-off:hover{border-color:var(--line)}
.wd-method input{position:absolute;opacity:0;pointer-events:none}
.wd-icon{width:34px;height:34px;flex-shrink:0;border-radius:10px;display:flex;align-items:center;justify-content:center;
  font-size:9.5px;font-weight:800;letter-spacing:.02em}
.wd-m-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.wd-m-name{font-size:13px;font-weight:700;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.wd-instant{font-size:9.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#0a7048;
  background:var(--green-wash);border-radius:20px;padding:2px 7px}
.wd-dest{font-family:var(--mono);font-size:11.5px;color:var(--slate);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wd-note{font-size:11.5px;color:var(--slate)}
.wd-note.link{color:var(--blue);font-weight:600}
.wd-note.link:hover{text-decoration:underline}
/* The tick is drawn rather than a native radio, so it matches the card. */
.wd-check{width:19px;height:19px;flex-shrink:0;border:2px solid var(--line);border-radius:50%;position:relative}
.wd-method.on .wd-check{border-color:var(--blue);background:var(--blue)}
.wd-method.on .wd-check::after{content:"";position:absolute;left:5px;top:2px;width:5px;height:9px;
  border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}

.wd-quote{background:var(--ink);color:#fff;border-radius:13px;padding:15px 17px}
.wd-quote-row{display:flex;align-items:baseline;justify-content:space-between;gap:14px}
.wd-quote-row span{font-size:12.5px;color:rgba(255,255,255,.62)}
.wd-quote-row b{font-family:var(--mono);font-size:21px;font-weight:800;letter-spacing:-.02em;text-align:right;
  word-break:break-word;min-width:0}
.wd-quote-rate{font-size:11.5px;color:rgba(255,255,255,.5);line-height:1.6;margin-top:8px}

/* ============ Small helpers ============ */
.browse-grid{margin-top:4px}
.dotsep{opacity:.4}
/* Tab panels carry no styling of their own; hidden does the work. */
.pd-panel{min-width:0}

/* ============ License picker ============ */
.tierm-wrap{position:fixed;inset:0;z-index:210;display:flex;align-items:center;justify-content:center;padding:24px;opacity:0;transition:opacity .18s}
.tierm-wrap.on{opacity:1}
.tierm-back{position:absolute;inset:0;background:rgba(6,8,20,.66);backdrop-filter:blur(3px)}
.tierm{position:relative;width:100%;max-width:600px;max-height:90vh;background:#fff;border-radius:20px;
  display:flex;flex-direction:column;overflow:hidden;box-shadow:0 30px 80px rgba(0,0,0,.4);
  transform:translateY(12px) scale(.98);transition:transform .2s cubic-bezier(.22,1,.36,1)}
.tierm-wrap.on .tierm{transform:none}
.tierm-x{position:absolute;top:11px;right:12px;width:30px;height:30px;border:0;border-radius:9px;cursor:pointer;z-index:3;
  background:rgba(255,255,255,.12);color:rgba(255,255,255,.75);display:flex;align-items:center;justify-content:center}
.tierm-x:hover{background:rgba(255,255,255,.22);color:#fff}
/* Head band: the item's identity, dark so the white tier cards below carry the eye. */
.tierm-head{display:flex;align-items:center;gap:13px;padding:15px 18px;background:linear-gradient(135deg,#0b0b0e,#14205c);color:#fff}
.tierm-thumb{width:44px;height:44px;border-radius:10px;overflow:hidden;flex-shrink:0;background:rgba(255,255,255,.09);
  display:flex;align-items:center;justify-content:center;border:1px solid rgba(255,255,255,.14)}
.tierm-thumb img{width:100%;height:100%;object-fit:cover}
.tierm-thumb-ph{font-family:var(--mono);font-size:17px;font-weight:800;color:rgba(255,255,255,.5)}
.tierm-id{min-width:0;flex:1}
.tierm-head h2{font-size:16.5px;font-weight:800;letter-spacing:-.02em;line-height:1.3;padding-right:38px}
.tierm-sub{font-size:11.5px;color:rgba(255,255,255,.62);margin-top:3px}
.tierm-sub b{color:rgba(255,255,255,.9);font-weight:600}
.tierm-stars{color:var(--amber);letter-spacing:.5px}
.tierm-body{padding:15px 18px 17px;overflow-y:auto;flex:1}
.tierm-eyebrow{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--slate);font-weight:600;margin-bottom:10px}
.tierm-loading{display:grid;grid-template-columns:1fr 1fr;gap:12px}
/* Side by side, because picking a tier is a comparison. */
.tierm-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}
.tierm-grid.one{grid-template-columns:1fr}
.tiercard{position:relative;display:flex;flex-direction:column;padding:15px;border:1.5px solid var(--line);border-radius:15px;cursor:pointer;
  transition:border-color .14s,box-shadow .14s,transform .14s;background:#fff}
.tiercard:hover{border-color:#c2cff0;transform:translateY(-2px);box-shadow:0 10px 26px rgba(10,17,48,.09)}
.tiercard.on{border-color:var(--blue);box-shadow:0 0 0 3px rgba(31,82,255,.13)}
.tiercard input{position:absolute;opacity:0;pointer-events:none}
.tiercard-tick{position:absolute;top:14px;right:14px;width:21px;height:21px;border-radius:50%;border:1.5px solid var(--line);
  background:#fff;color:#fff;display:flex;align-items:center;justify-content:center;transition:background .14s,border-color .14s}
.tiercard-tick svg{opacity:0;transition:opacity .14s}
.tiercard.on .tiercard-tick{background:var(--blue);border-color:var(--blue)}
.tiercard.on .tiercard-tick svg{opacity:1}
.tiercard-badge{align-self:flex-start;font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  background:var(--blue-wash);color:var(--blue);padding:3px 9px;border-radius:20px;margin-bottom:9px;line-height:1.5}
/* Keeps its row so both cards align, without drawing anything. min-height is
   needed because an empty box generates no line and would collapse to nothing. */
.tiercard-badge{min-height:21px}
.tiercard-badge.empty{visibility:hidden}
.tiercard-name{font-weight:700;font-size:14.5px;padding-right:28px}
.tiercard-price{font-family:var(--mono);font-size:25px;font-weight:800;letter-spacing:-.03em;margin:6px 0 2px;line-height:1}
.tiercard-price .free{color:var(--green)}
.tiercard-note{font-size:11.5px;color:var(--slate);line-height:1.45;min-height:33px}
.tiercard-grants{display:flex;flex-direction:column;gap:7px;margin-top:12px;padding-top:12px;border-top:1px solid var(--line-soft)}
.tiercard-grants span{display:flex;align-items:flex-start;gap:7px;font-size:12px;color:var(--ink-soft);line-height:1.45}
.tiercard-grants svg{color:var(--green);flex-shrink:0;margin-top:2px}
.tierm-foot{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  padding:13px 18px calc(15px + env(safe-area-inset-bottom));border-top:1px solid var(--line);background:var(--blue-tint)}
.tierm-details{display:inline-flex;align-items:center;gap:5px;font-size:13.5px;font-weight:600;color:var(--blue)}
.tierm-details:hover{color:var(--blue-deep);text-decoration:underline}
.tierm-foot .btn{padding:11px 22px;font-size:14px}
@media(max-width:640px){
  .tierm-wrap{padding:0;align-items:flex-end}
  .tierm{max-width:none;border-radius:20px 20px 0 0;max-height:94vh;transform:translateY(100%)}
  .tierm-wrap.on .tierm{transform:none}
  .tierm-grid,.tierm-loading{grid-template-columns:1fr}
  .tierm-head{padding:14px 16px}
  .tierm-thumb{width:40px;height:40px}
  .tierm-head h2{font-size:15.5px}
  .tierm-body{padding:14px 16px 16px}
  .tiercard-note{min-height:0}
  .tiercard-price{font-size:23px}
  .tierm-foot{padding:12px 16px calc(14px + env(safe-area-inset-bottom))}
  .tierm-foot .btn{flex:1;justify-content:center}
}
@media(prefers-reduced-motion:reduce){.tierm-wrap,.tierm,.tiercard{transition:none}}

/* ============ Auth dialog ============ */
.authm-wrap{position:fixed;inset:0;z-index:220;display:flex;align-items:center;justify-content:center;padding:20px;opacity:0;transition:opacity .18s}
.authm-wrap.on{opacity:1}
.authm-back{position:absolute;inset:0;background:rgba(6,8,20,.62);backdrop-filter:blur(2px)}
/* Two panes on desktop, the brand panel beside the form, exactly like the
   /login page. Collapses to the form alone on small screens. */
.authm{position:relative;width:100%;max-width:820px;max-height:92vh;background:#fff;border-radius:20px;overflow:hidden;
  display:grid;grid-template-columns:1fr 1fr;box-shadow:0 24px 70px rgba(0,0,0,.35);
  transform:translateY(10px) scale(.985);transition:transform .18s}
.authm-wrap.on .authm{transform:none}
.authm .auth-aside,.authp-card .auth-aside{display:flex}
.authm .auth-aside-in,.authp-card .auth-aside-in{padding:34px 30px;max-width:none}
.authm .auth-aside-in h2,.authp-card .auth-aside-in h2{font-size:25px;margin:20px 0 12px}
.authm .auth-aside-in p,.authp-card .auth-aside-in p{font-size:14px}
.authm .auth-logo-img,.authp-card .auth-aside .auth-logo-img{height:34px}
.authm .auth-aside-foot,.authp-card .auth-aside-foot{position:static;margin-top:26px;padding:0}
.authm-pane{padding:30px 28px 26px;overflow-y:auto;max-height:92vh}
.authm-x{position:absolute;top:12px;right:12px;width:36px;height:36px;border:0;background:none;color:var(--slate-light);border-radius:9px;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:3}
.authm-x:hover{background:var(--blue-tint);color:var(--ink)}
/* Below the two-pane width the brand panel is dropped rather than squeezed. */
@media(max-width:760px){
  .authm{grid-template-columns:1fr;max-width:410px}
  .authm .auth-aside{display:none}
}
/* The standalone /login and /register pages present the same pane as the header
   dialog, so these selectors cover both. Widened rather than duplicated: two
   copies of the values would drift the moment one is touched. */
.authm-head,.authp-pane .auth-head{text-align:center;margin-bottom:16px}
.authm-logo img{height:30px;width:auto;margin:0 auto 16px;display:block}
/* The brand panel beside the form already carries the mark, so the form pane
   only shows its own logo once that panel is dropped on small screens. */
.authm .authm-logo{display:none}
@media(max-width:760px){.authm .authm-logo{display:block}}
.authm-head h2,.authp-pane .auth-head h1{font-size:22px;font-weight:800;letter-spacing:-.02em}
.authm-head p,.authp-pane .auth-head p{font-size:13.5px;color:var(--slate);margin-top:6px}
.authm-form,.authp-pane .auth-form{display:flex;flex-direction:column;gap:12px;margin-top:0}
.authm-btn{width:100%;justify-content:center;padding:13px;margin-top:2px}
.authm-btn:disabled{opacity:.6;cursor:not-allowed}
.authm-alt,.authp-pane .auth-alt{text-align:center;font-size:13.5px;color:var(--slate);margin:4px 0 0}
.authm-msg{padding:11px 14px;border-radius:11px;font-size:13px;line-height:1.5;margin-bottom:14px}
.authm-msg.err{background:#fdeaea;border:1px solid #f6c9c9;color:#b3261e}
.authm-msg.ok{background:var(--green-wash);border:1px solid #b8ead6;color:#0a7a56}
@media(max-width:480px){
  .authm-wrap{padding:0;align-items:flex-end}
  /* On a phone it reads as a sheet rising from the bottom, which is easier to
     reach one-handed than a centred box. */
  .authm{max-width:none;border-radius:20px 20px 0 0;max-height:94vh;transform:translateY(100%)}
  .authm-wrap.on .authm{transform:none}
  .authm-pane{padding:26px 20px calc(24px + env(safe-area-inset-bottom));max-height:94vh}
}
@media(prefers-reduced-motion:reduce){
  .authm-wrap,.authm{transition:none}
}

/* ============ Touch input sizing ============ */
/* Safari on iOS zooms the page in whenever you focus a field whose text is
   under 16px, and it does not zoom back out afterwards. Touch devices get 16px
   on every control so tapping search never jumps the layout. Pointer devices
   keep the tighter sizes the design uses.
   Must stay last in the file: these selectors match the earlier ones exactly,
   so they only win on source order. */
@media (hover: none) and (pointer: coarse) {
  input, select, textarea,
  .search input, .hero-search input, .auth-input, .sortsel, .rv-write textarea {
    font-size: 16px;
  }
}

/* ═══════════════════════════════════════════════════════════
   HELP CENTRE
   Content is hardcoded in lib/help.js. Two pages share these
   styles: /help (topic cards) and /help/:topic (answers).
   ═══════════════════════════════════════════════════════════ */

.hc-hero{background:linear-gradient(180deg,var(--blue-tint) 0%,#fff 100%);border-bottom:1px solid var(--line-soft);padding:0}
.hc-hero-in{display:grid;grid-template-columns:1fr 400px;gap:40px;align-items:center;padding:64px 0 72px}
.hc-hero-copy h1{font-size:46px;line-height:1.08;letter-spacing:-.025em;margin:20px 0 14px}
.hc-hero-copy h1 .dot{color:var(--blue)}
.hc-hero-copy>p{color:var(--slate);font-size:16.5px;line-height:1.62;max-width:52ch;margin:0}

/* Search */
.hc-search{position:relative;margin-top:26px;max-width:520px}
.hc-search-box{display:flex;align-items:center;gap:11px;background:#fff;border:1.5px solid var(--line);
  border-radius:13px;padding:0 16px;box-shadow:var(--shadow);transition:border-color .15s,box-shadow .15s}
.hc-search-box:focus-within{border-color:var(--blue);box-shadow:0 0 0 4px var(--blue-wash)}
.hc-search-box svg{color:var(--slate-light);flex-shrink:0}
.hc-search-box input{flex:1;border:0;outline:0;background:none;padding:16px 0;font-family:var(--sans);
  font-size:15.5px;color:var(--ink);min-width:0}
.hc-search-box input::placeholder{color:var(--slate-light)}
.hc-search-box input::-webkit-search-cancel-button{-webkit-appearance:none}

.hc-results{position:absolute;top:calc(100% + 8px);left:0;right:0;z-index:60;background:#fff;
  border:1px solid var(--line);border-radius:13px;box-shadow:var(--shadow-lg);overflow:hidden;max-height:390px;overflow-y:auto}
.hc-res{display:flex;flex-direction:column;gap:3px;padding:12px 16px;border-bottom:1px solid var(--line-soft);
  text-decoration:none;transition:background .12s}
.hc-res:last-child{border-bottom:0}
.hc-res:hover,.hc-res.on{background:var(--blue-tint)}
.hc-res-q{font-size:14.5px;font-weight:600;color:var(--ink);line-height:1.4}
.hc-res-t{font-size:11.5px;font-weight:600;color:var(--blue);text-transform:uppercase;letter-spacing:.05em}
.hc-res-none{padding:16px;font-size:14.5px;color:var(--slate)}
.hc-res-none a{color:var(--blue);font-weight:600}

/* Popular chips */
.hc-popular{display:flex;align-items:center;flex-wrap:wrap;gap:9px;margin-top:22px}
.hc-chips{display:flex;align-items:center;flex-wrap:wrap;gap:9px;min-width:0}
.hc-popular-l{font-family:var(--mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;
  font-weight:600;color:var(--slate-light);margin-right:3px}
.hc-chip{display:inline-flex;align-items:center;gap:7px;background:#fff;border:1px solid var(--line);
  border-radius:30px;padding:8px 15px;font-size:13.5px;font-weight:600;color:var(--ink-soft);
  text-decoration:none;transition:border-color .15s,color .15s,transform .15s}
.hc-chip:hover{border-color:var(--blue);color:var(--blue);transform:translateY(-1px)}
.hc-chip svg{color:var(--slate-light)}
.hc-chip:hover svg{color:var(--blue)}

/* Hero art: flat cards drifting behind a badge. Decorative, no content. */
.hc-hero-art{position:relative;height:290px}
.hc-deco-card{position:absolute;background:#fff;border:1px solid var(--line);border-radius:15px;
  box-shadow:var(--shadow);padding:15px;width:158px;display:flex;flex-direction:column;gap:9px}
.hc-deco-card svg{color:var(--blue)}
.hc-deco-card span{display:block;height:7px;border-radius:4px;background:var(--line-soft)}
.hc-deco-card span:last-child{width:58%}
.hc-deco-1{top:6px;left:8px;transform:rotate(-6deg);animation:hcFloat 7s ease-in-out infinite}
.hc-deco-2{top:96px;right:12px;transform:rotate(5deg);animation:hcFloat 7s ease-in-out infinite .9s}
.hc-deco-3{bottom:2px;left:44px;transform:rotate(-2deg);animation:hcFloat 7s ease-in-out infinite 1.8s}
.hc-deco-orb{position:absolute;top:52%;left:52%;transform:translate(-50%,-50%);width:104px;height:104px;
  border-radius:50%;background:var(--blue);color:#fff;display:flex;align-items:center;justify-content:center;
  box-shadow:0 16px 44px rgba(31,82,255,.34)}
@keyframes hcFloat{0%,100%{translate:0 0}50%{translate:0 -11px}}
@media(prefers-reduced-motion:reduce){.hc-deco-1,.hc-deco-2,.hc-deco-3{animation:none}}

/* Topic cards */
.hc-topics{padding:66px 0}
.hc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.hc-card{background:#fff;border:1px solid var(--line);border-radius:17px;padding:24px;
  display:flex;flex-direction:column;transition:border-color .16s,box-shadow .16s,transform .16s}
.hc-card:hover{border-color:#d6dbe8;box-shadow:var(--shadow);transform:translateY(-2px)}
.hc-card-top{display:flex;gap:14px;margin-bottom:16px}
.hc-card-ic{width:42px;height:42px;border-radius:12px;background:var(--blue-wash);color:var(--blue);
  display:flex;align-items:center;justify-content:center;flex-shrink:0}
.hc-card-ic.lg{width:54px;height:54px;border-radius:15px}
.hc-card h2{font-size:17.5px;letter-spacing:-.01em;margin:2px 0 5px;line-height:1.25}
.hc-card h2 a{color:var(--ink);text-decoration:none}
.hc-card h2 a:hover{color:var(--blue)}
.hc-card-blurb{font-size:13.5px;color:var(--slate);line-height:1.5;margin:0}

.hc-qlist{list-style:none;margin:0 0 16px;padding:0;border-top:1px solid var(--line-soft)}
.hc-qlist li{border-bottom:1px solid var(--line-soft)}
.hc-qlist a{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 0;
  font-size:14.5px;line-height:1.45;color:var(--ink-soft);text-decoration:none;transition:color .13s}
.hc-qlist a:hover{color:var(--blue)}
.hc-qlist a svg{color:var(--line);flex-shrink:0;transition:color .13s,transform .13s}
.hc-qlist a:hover svg{color:var(--blue);transform:translateX(2px)}
.hc-more{margin-top:auto;font-size:13.5px;font-weight:700;color:var(--blue);text-decoration:none}
.hc-more:hover span{margin-left:3px}
.hc-more span{display:inline-block;transition:margin-left .15s}

/* Topic page */
.hc-topic-hero{background:var(--blue-tint);border-bottom:1px solid var(--line-soft);padding:0}
.hc-topic-in{display:flex;align-items:flex-end;justify-content:space-between;gap:36px;padding:34px 0 38px}
.hc-topic-id{min-width:0}
.hc-crumb{display:flex;align-items:center;flex-wrap:wrap;gap:9px;font-size:13.5px;color:var(--slate-light);margin-bottom:18px}
.hc-crumb a{color:var(--slate);text-decoration:none}
.hc-crumb a:hover{color:var(--blue)}
.hc-crumb [aria-current]{color:var(--ink);font-weight:600}
.hc-topic-head{display:flex;gap:16px;align-items:center}
.hc-topic-head h1{font-size:33px;letter-spacing:-.022em;margin:0 0 5px;line-height:1.15}
.hc-topic-head p{font-size:14.5px;color:var(--slate);margin:0;line-height:1.5}
.hc-search.sm{margin-top:0;width:330px;flex-shrink:0}
.hc-search.sm .hc-search-box input{padding:13px 0;font-size:14.5px}

.hc-topic-body{padding:44px 0 60px}

/* The seller level table inside an answer. */
.hc-table{width:100%;border-collapse:collapse;margin:4px 0 13px;font-size:14px}
.hc-table th{text-align:left;padding:9px 12px;background:var(--blue-tint);color:var(--slate);
  font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--line)}
.hc-table td{padding:10px 12px;border-bottom:1px solid var(--line-soft);font-variant-numeric:tabular-nums}
.hc-table tr:last-child td{border-bottom:0}
.hc-table td:last-child{font-weight:700;color:var(--ink)}

.hc-othertopics{display:flex;align-items:center;flex-wrap:wrap;gap:9px;margin-top:30px}
.hc-ot-l{font-family:var(--mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;
  font-weight:600;color:var(--slate-light);margin-right:3px}

/* Ask band */

/* Responsive */
@media(max-width:1000px){
  .hc-hero-in{grid-template-columns:1fr;padding:48px 0 52px}
  .hc-hero-art{display:none}
  .hc-hero-copy h1{font-size:38px}
  .hc-grid{grid-template-columns:repeat(2,1fr)}
  .hc-topic-in{flex-direction:column;align-items:stretch;gap:22px}
  .hc-search.sm{width:100%}
}
@media(max-width:640px){
  .hc-hero-in{padding:38px 0 42px}
  .hc-hero-copy h1{font-size:31px}
  .hc-hero-copy>p{font-size:15px}
  .hc-topics{padding:44px 0}
  .hc-grid{grid-template-columns:1fr;gap:16px}
  .hc-card{padding:20px}
  .hc-topic-head{gap:13px}
  .hc-topic-head h1{font-size:25px}
  .hc-card-ic.lg{width:44px;height:44px;border-radius:13px}
  .hc-topic-body{padding:32px 0 46px}
  /* Scroll the level table rather than letting it widen the page. */
  .hc-art-body .hc-table{display:block;overflow-x:auto;white-space:nowrap}
}

/* ── Topic page: question rows linking to articles ── */
.hc-qrows{background:#fff;border:1px solid var(--line);border-radius:17px;overflow:hidden;box-shadow:var(--shadow)}
.hc-qrow{display:flex;align-items:center;gap:14px;padding:19px 24px;text-decoration:none;
  border-bottom:1px solid var(--line-soft);transition:background .13s}
.hc-qrow:last-child{border-bottom:0}
.hc-qrow:hover{background:var(--blue-tint)}
.hc-qrow:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
.hc-qrow-ic{color:var(--slate-light);display:flex;flex-shrink:0;transition:color .13s}
.hc-qrow:hover .hc-qrow-ic{color:var(--blue)}
.hc-qrow h2{flex:1;font-size:16px;font-weight:650;letter-spacing:-.008em;line-height:1.4;margin:0;
  color:var(--ink);transition:color .13s}
.hc-qrow:hover h2{color:var(--blue)}
.hc-qrow-go{color:var(--line);font-size:17px;flex-shrink:0;transition:color .13s,transform .16s}
.hc-qrow:hover .hc-qrow-go{color:var(--blue);transform:translateX(3px)}

/* ── Article page ── */
.hc-art-wrap{padding:34px 0 64px}
.hc-art-grid{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:48px;align-items:start}
.hc-article{min-width:0}
.hc-article h1{font-size:33px;letter-spacing:-.024em;line-height:1.2;margin:0 0 14px}
.hc-art-meta{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--slate-light);
  padding-bottom:24px;border-bottom:1px solid var(--line-soft);margin-bottom:28px}
.hc-art-meta svg{color:var(--slate-light)}

.hc-art-body{font-size:16px;line-height:1.72;color:var(--ink-soft)}
.hc-art-body>p:first-child{font-size:17.5px;line-height:1.62;color:var(--ink);font-weight:500}
.hc-art-body h2{font-size:20px;letter-spacing:-.014em;line-height:1.3;color:var(--ink);margin:34px 0 12px}
.hc-art-body p{margin:0 0 16px}
.hc-art-body a{color:var(--blue);font-weight:600;text-decoration:none}
.hc-art-body a:hover{text-decoration:underline}
.hc-art-body strong{color:var(--ink);font-weight:670}
.hc-art-body ul,.hc-art-body ol{margin:0 0 16px;padding-left:22px}
.hc-art-body ul{list-style:disc}
.hc-art-body ol{list-style:decimal}
.hc-art-body li{margin-bottom:9px;padding-left:3px}
.hc-art-body li:last-child{margin-bottom:0}
.hc-art-body .hc-table{margin:6px 0 18px}

/* Was this helpful */
.hc-helpful{margin-top:44px;background:var(--blue-tint);border:1px solid var(--line);
  border-radius:15px;padding:24px}
.hc-helpful p{margin:0;font-size:15px;color:var(--ink-soft);line-height:1.6}
.hc-helpful strong{color:var(--ink)}
.hc-helpful-ask{display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap}
.hc-helpful-ask p{font-weight:650;color:var(--ink);font-size:15.5px}
.hc-helpful-btns{display:flex;gap:9px}
.hc-helpful-btns .btn{background:#fff;padding:9px 26px}
.hc-helpful-no p{margin-bottom:16px}

/* Sidebar */
.hc-art-side{position:sticky;top:calc(var(--nav-h) + 16px);display:flex;flex-direction:column;gap:18px}
.hc-art-side .hc-search{margin-top:0;width:100%}
.hc-side-box{background:#fff;border:1px solid var(--line);border-radius:15px;padding:20px}
.hc-side-box h2,.hc-side-box h3{font-size:13.5px;font-weight:700;text-transform:uppercase;
  letter-spacing:.05em;color:var(--slate);margin:0 0 6px}
.hc-side-box ul{list-style:none;margin:0;padding:0}
.hc-side-box li{border-bottom:1px solid var(--line-soft)}
.hc-side-box li:last-child{border-bottom:0}
.hc-side-box li a{display:flex;align-items:flex-start;gap:10px;padding:12px 0;font-size:14px;
  line-height:1.45;color:var(--ink-soft);text-decoration:none;transition:color .13s}
.hc-side-box li a:hover{color:var(--blue)}
.hc-side-box li a svg{color:var(--slate-light);flex-shrink:0;margin-top:2px;transition:color .13s}
.hc-side-box li a:hover svg{color:var(--blue)}
.hc-side-box li.on>a{color:var(--blue);font-weight:650}
.hc-side-back{font-size:13.5px;font-weight:650;color:var(--slate);text-decoration:none;padding-left:2px}
.hc-side-back:hover{color:var(--blue)}

@media(max-width:1000px){
  .hc-art-grid{grid-template-columns:1fr;gap:32px}
  .hc-art-side{position:static}
  /* Search first on the landing and topic pages, but on an article the reader
     came for the article: send the sidebar below it. */
  .hc-art-side{order:2}
}
@media(max-width:640px){
  .hc-art-wrap{padding:24px 0 44px}
  .hc-article h1{font-size:25px}
  .hc-art-body{font-size:15.5px}
  .hc-art-body>p:first-child{font-size:16.5px}
  .hc-art-body h2{font-size:18px;margin:28px 0 10px}
  .hc-qrow{padding:16px 17px;gap:11px}
  .hc-qrow h2{font-size:15px}
  .hc-helpful{padding:20px}
  .hc-helpful-ask{flex-direction:column;align-items:stretch;gap:14px}
  .hc-helpful-btns .btn{flex:1}
}

/* ═══════════════════════════════════════════════════════════
   BLOG
   Posts are hardcoded in lib/blog.js. Covers are generated from
   the category rather than uploaded, so a new post looks right
   with no image to manage.
   ═══════════════════════════════════════════════════════════ */

.bl-hero{background:var(--blue-tint);border-bottom:1px solid var(--line-soft);padding:0}
.bl-hero-in{display:flex;align-items:flex-end;justify-content:space-between;gap:36px;padding:34px 0 38px}
.bl-hero-in h1{font-size:33px;letter-spacing:-.024em;margin:0 0 6px;line-height:1.15}
.bl-hero-in>div>p{font-size:14.5px;color:var(--slate);margin:0;line-height:1.5;max-width:56ch}

.bl-body{padding:44px 0 64px}
.bl-layout{display:grid;grid-template-columns:290px minmax(0,1fr);gap:34px;align-items:start}
.bl-main{min-width:0;order:2}
.bl-side{order:1;position:sticky;top:calc(var(--nav-h) + 16px);display:flex;flex-direction:column;gap:18px}

/* Sidebar boxes */
.bl-box{background:#fff;border:1px solid var(--line);border-radius:15px;padding:18px 20px}
.bl-box h2{display:flex;align-items:center;gap:9px;font-size:13.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;color:var(--slate);margin:0 0 6px}
.bl-box h2 svg{color:var(--blue)}
.bl-box ul{list-style:none;margin:0;padding:0}

.bl-cats li{border-bottom:1px solid var(--line-soft)}
.bl-cats li:last-child{border-bottom:0}
.bl-cats a{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 0;
  font-size:14.5px;color:var(--ink-soft);text-decoration:none;transition:color .13s}
.bl-cats a:hover{color:var(--blue)}
.bl-cats li.on>a{color:var(--blue);font-weight:650}
.bl-count{font-size:11.5px;font-weight:700;color:var(--slate-light);background:var(--blue-tint);
  border-radius:20px;padding:2px 9px;font-variant-numeric:tabular-nums;flex-shrink:0}
.bl-cats li.on .bl-count,.bl-cats a:hover .bl-count{background:var(--blue-wash);color:var(--blue)}

.bl-recent li,.bl-items li{border-bottom:1px solid var(--line-soft)}
.bl-recent li:last-child,.bl-items li:last-child{border-bottom:0}
.bl-recent a,.bl-items a{display:flex;align-items:center;gap:11px;padding:11px 0;text-decoration:none}
/* Wider than tall, as in the reference, so the crop of an illustration keeps
   enough of the subject to be recognisable at this size. */
.bl-recent-th{width:54px;height:44px;border-radius:10px;display:flex;align-items:center;
  justify-content:center;flex-shrink:0;color:#fff;overflow:hidden}
.bl-recent-th.art{background:#eef3ff}
.bl-recent-th.art img,.bl-related-th.art img{width:100%;height:100%;object-fit:cover;display:block}
.bl-related-th.art{background:#eef3ff}
.bl-recent-t,.bl-item-t{display:flex;flex-direction:column;gap:3px;min-width:0}
.bl-recent-title{font-size:13.5px;font-weight:600;line-height:1.35;color:var(--ink-soft);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;transition:color .13s}
.bl-recent a:hover .bl-recent-title{color:var(--blue)}
.bl-recent-d{font-size:11.5px;color:var(--slate-light)}

.bl-item-th{width:40px;height:40px;border-radius:10px;background:var(--blue-tint);flex-shrink:0;
  display:flex;align-items:center;justify-content:center;color:var(--slate-light);overflow:hidden}
.bl-item-th img{width:100%;height:100%;object-fit:cover}
.bl-item-name{font-size:13.5px;font-weight:600;line-height:1.35;color:var(--ink-soft);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;transition:color .13s}
.bl-items a:hover .bl-item-name{color:var(--blue)}
.bl-item-price{font-size:12.5px;font-weight:700;color:var(--blue);font-variant-numeric:tabular-nums}

/* Cards */
.bl-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.bl-card{background:#fff;border:1px solid var(--line);border-radius:16px;overflow:hidden;
  display:flex;flex-direction:column;transition:border-color .16s,box-shadow .16s,transform .16s}
.bl-card:hover{border-color:#d6dbe8;box-shadow:var(--shadow);transform:translateY(-2px)}
.bl-card-in{padding:18px;display:flex;flex-direction:column;flex:1}
.bl-card h2{font-size:17px;letter-spacing:-.012em;line-height:1.32;margin:0 0 9px}
.bl-card h2 a{color:var(--ink);text-decoration:none}
.bl-card h2 a:hover{color:var(--blue)}
.bl-card p{font-size:13.5px;line-height:1.58;color:var(--slate);margin:0 0 14px;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}

/* Generated cover: a category gradient, a faint grid and two soft discs behind
   the icon. Built from gradients rather than an image so a new post needs no
   asset, and so the whole thing costs nothing to load. The layers are what stop
   it reading as an unfilled placeholder. */
.bl-cover{display:flex;align-items:center;justify-content:center;height:150px;color:#fff;
  position:relative;overflow:hidden;text-decoration:none}
.bl-cover::before{content:"";position:absolute;inset:0;opacity:.5;
  background-image:linear-gradient(rgba(255,255,255,.14) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.14) 1px,transparent 1px);
  background-size:26px 26px;
  /* Fades the grid out towards the middle so it never fights the icon. */
  -webkit-mask-image:radial-gradient(circle at 50% 50%,transparent 32%,#000 78%);
  mask-image:radial-gradient(circle at 50% 50%,transparent 32%,#000 78%)}
.bl-cover::after{content:"";position:absolute;inset:0;
  background:
    radial-gradient(circle at 84% 16%, rgba(255,255,255,.30), transparent 42%),
    radial-gradient(circle at 12% 88%, rgba(0,0,0,.20), transparent 46%)}
.bl-cover svg{position:relative;z-index:1;opacity:.97;
  filter:drop-shadow(0 5px 14px rgba(0,0,0,.28));
  transition:transform .28s cubic-bezier(.22,.8,.28,1)}
.bl-card:hover .bl-cover svg{transform:scale(1.05)}

/* An illustrated cover brings its own ground, so the gradient and the grid
   would only show through as noise behind it. */
.bl-cover.art{background:#eef3ff;padding:0}
.bl-cover.art::before,.bl-cover.art::after{display:none}
.bl-cover.art img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .35s cubic-bezier(.22,.8,.28,1)}
.bl-card:hover .bl-cover.art img{transform:scale(1.04)}
@media(prefers-reduced-motion:reduce){
  .bl-card:hover .bl-cover.art img,.bl-card:hover .bl-cover svg{transform:none}
}
.bl-cover.big{height:230px;border-radius:16px;margin:0 0 30px}
.cat-seller-tips{background:linear-gradient(135deg,#1f52ff,#0b39d6)}
.cat-buyer-guides{background:linear-gradient(135deg,#0f9d76,#10b981)}
.cat-market-insights{background:linear-gradient(135deg,#3b3f52,#0b0b0e)}
.cat-developer-resources{background:linear-gradient(135deg,#5b46e0,#8b5cf6)}
.cat-marketplace-news{background:linear-gradient(135deg,#d18414,#f5a524)}

.bl-meta{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.bl-meta time{font-size:12px;color:var(--slate-light);font-variant-numeric:tabular-nums}
.bl-tag{display:inline-flex;font-size:11px;font-weight:700;text-transform:uppercase;
  letter-spacing:.05em;color:var(--blue);background:var(--blue-wash);border-radius:20px;
  padding:4px 11px;text-decoration:none;transition:background .13s}
.bl-tag:hover{background:#dfe6ff}
.bl-read{margin-top:auto;font-size:13.5px;font-weight:700;color:var(--blue);text-decoration:none}
.bl-read span{display:inline-block;transition:margin-left .15s}
.bl-read:hover span{margin-left:3px}

/* Pagination */
.bl-pager{display:flex;align-items:center;justify-content:center;gap:7px;flex-wrap:wrap;margin-top:34px}
.bl-pg{min-width:38px;height:38px;padding:0 11px;display:inline-flex;align-items:center;
  justify-content:center;border:1px solid var(--line);border-radius:10px;background:#fff;
  font-size:14px;font-weight:600;color:var(--ink-soft);text-decoration:none;
  font-variant-numeric:tabular-nums;transition:border-color .13s,color .13s,background .13s}
.bl-pg:hover{border-color:var(--blue);color:var(--blue)}
.bl-pg.on{background:var(--blue);border-color:var(--blue);color:#fff}
.bl-pg.off{opacity:.4;pointer-events:none}

.bl-empty{background:#fff;border:1px solid var(--line);border-radius:16px;padding:52px 26px;text-align:center}
.bl-empty svg{color:var(--slate-light);margin-bottom:12px}
.bl-empty h2{font-size:20px;margin:0 0 8px;letter-spacing:-.015em}
.bl-empty p{font-size:14.5px;color:var(--slate);margin:0;line-height:1.6}
.bl-empty a{color:var(--blue);font-weight:600;text-decoration:none}

/* Single post */
.bl-post-wrap{padding-top:30px}
.bl-post-head{margin:14px 0 22px}
.bl-post-head h1{font-size:35px;letter-spacing:-.026em;line-height:1.16;margin:12px 0 12px}
.bl-post-meta{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--slate-light)}
.bl-post-body{max-width:none}

.bl-related{margin-top:44px;padding-top:30px;border-top:1px solid var(--line)}
.bl-related>h2{font-size:20px;letter-spacing:-.015em;margin:0 0 16px}
.bl-related-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.bl-related-card{display:flex;gap:12px;align-items:flex-start;background:#fff;border:1px solid var(--line);
  border-radius:13px;padding:14px;text-decoration:none;transition:border-color .15s,transform .15s}
.bl-related-card:hover{border-color:var(--blue);transform:translateY(-2px)}
.bl-related-th{width:52px;height:44px;border-radius:10px;display:flex;align-items:center;
  justify-content:center;color:#fff;flex-shrink:0;overflow:hidden}
.bl-related-t{display:flex;flex-direction:column;gap:4px;min-width:0}
.bl-related-cat{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--blue)}
.bl-related-title{font-size:14px;font-weight:650;line-height:1.38;color:var(--ink);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}

/* Responsive */
@media(max-width:1100px){
  .bl-layout{grid-template-columns:1fr;gap:30px}
  /* Sidebar is reference material, so it follows the posts on narrow screens. */
  .bl-main{order:1}
  .bl-side{order:2;position:static}
  .bl-grid{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:1000px){
  .bl-hero-in{flex-direction:column;align-items:stretch;gap:20px}
}
@media(max-width:640px){
  .bl-hero-in{padding:26px 0 30px}
  .bl-hero-in h1{font-size:26px}
  .bl-body{padding:30px 0 46px}
  .bl-grid{grid-template-columns:1fr;gap:16px}
  .bl-cover{height:170px}
  .bl-cover.big{height:170px;margin-bottom:24px}
  .bl-post-head h1{font-size:26px}
  .bl-related-grid{grid-template-columns:1fr}
  .bl-pg{min-width:36px;height:36px}
}

/* ═══════════════════════════════════════════════════════════
   POLICY PAGES
   One template (views/pages/legal.ejs) renders every entry in
   lib/legal.js, so these styles cover all of them.
   ═══════════════════════════════════════════════════════════ */

/* White, not tinted. The document used to be a white card floating on a tinted
   page; now it is the page, so the tint moves off the ground and onto the things
   that sit on it: the sidebar, the callouts, the contact and Read next cards. */
.lg-wrap{background:var(--white);padding:30px 0 60px;border-top:1px solid var(--line-soft)}
/* Wider than the 1240px reading measure the rest of the site uses, because this
   layout is two columns: at 1240 the document column was only 898px and the
   page carried 100px of empty gutter either side. The prose inside is capped
   separately below, so widening the shell does not lengthen the lines. */
.lg-wrap>.wrap{max-width:1400px}
.lg-layout{display:grid;grid-template-columns:320px minmax(0,1fr);gap:28px;align-items:start}

/* ── Document sidebar ── */
.lg-side{position:sticky;top:calc(var(--nav-h) + 16px);display:flex;flex-direction:column;gap:16px}
/* Tinted now that the page behind it is white. */
.lg-side-box{background:var(--blue-tint);border:0;border-radius:16px;padding:16px}
.lg-side-box h2{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;
  color:var(--slate-light);margin:0 0 10px;padding:0 6px}
.lg-docs{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.lg-docs a,.lg-doc-soon{display:flex;align-items:center;gap:11px;padding:10px 11px;border-radius:10px;
  font-size:13.5px;line-height:1.35;color:var(--ink-soft);text-decoration:none;transition:background .13s,color .13s}
.lg-docs a>span:nth-child(2),.lg-doc-soon>span:nth-child(2){flex:1;min-width:0}
/* White on the tinted box, the reverse of before: the box carries the tint now,
   so a tinted hover would have been the row painting its own background. */
.lg-docs a:hover{background:#fff;color:var(--blue)}
.lg-doc-ic{display:flex;color:var(--slate-light);flex-shrink:0;transition:color .13s}
.lg-docs a:hover .lg-doc-ic{color:var(--blue)}
.lg-docs li.on>a{background:var(--blue);color:#fff;font-weight:650}
.lg-docs li.on .lg-doc-ic{color:#fff}
.lg-doc-go{color:#fff;font-size:16px;line-height:1}
.lg-doc-soon{color:var(--slate-light);cursor:default}
.lg-doc-badge{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  background:var(--line-soft);color:var(--slate-light);border-radius:20px;padding:3px 7px;flex-shrink:0}

.lg-help{text-align:left}
.lg-help-ic{display:inline-flex;width:38px;height:38px;border-radius:11px;background:var(--blue-wash);
  color:var(--blue);align-items:center;justify-content:center;margin-bottom:10px}
.lg-help h2{font-size:15px;font-weight:700;text-transform:none;letter-spacing:-.01em;
  color:var(--ink);margin:0 0 6px;padding:0}
.lg-help p{font-size:13px;line-height:1.55;color:var(--slate);margin:0 0 14px}
.lg-help-btn{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;color:var(--ink);background:#fff;
  border:1px solid var(--line);border-radius:9px;padding:9px 14px;text-decoration:none;
  transition:border-color .14s,color .14s}
.lg-help-btn:hover{border-color:var(--blue);color:var(--blue)}

/* ── The document itself ── */
/* No card, no gradient rule across the top. A policy is the page, not an object
   on it: the card was a frame around content that already had its own shape,
   and the blue bar was decoration doing the work a heading should do. */
.lg-doc{min-width:0;padding-top:4px}

.lg-official{display:inline-flex;align-items:center;gap:7px;font-size:10.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.09em;color:var(--blue);background:var(--blue-wash);
  border-radius:20px;padding:6px 13px;margin-bottom:16px}
.lg-doc h1{font-size:33px;letter-spacing:-.026em;line-height:1.16;margin:0 0 14px}
.lg-chip{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;font-weight:650;
  color:var(--blue);background:var(--blue-wash);border-radius:20px;padding:6px 13px}
.lg-meta{font-size:13px;color:var(--slate-light);margin:14px 0 0}
.lg-intro{margin-top:18px;padding-top:20px;border-top:1px solid var(--line-soft)}
.lg-intro p{font-size:16px;line-height:1.68;color:var(--ink-soft);margin:0 0 12px}
.lg-intro p:last-child{margin-bottom:0}

/* Callout, info by default and amber for warn */
.lg-note{display:flex;gap:13px;background:var(--blue-tint);border:1px solid #e2e8ff;
  border-radius:13px;padding:16px 18px;margin:24px 0}
.lg-note p{font-size:14px;line-height:1.65;color:var(--slate);margin:0}
.lg-note p:last-child{margin-bottom:0}
.lg-note-ic{display:flex;color:var(--blue);flex-shrink:0;margin-top:1px}
.lg-note.warn{background:#fff8ec;border-color:#f7e2bd}
.lg-note.warn .lg-note-ic{color:#b06f05}
.lg-note.warn p{color:#7a4e05}
/* Inside a section body the callout has no icon slot, so it needs its own rail. */
.lg-sec-body .lg-note{display:block;border-left:3px solid var(--blue)}
.lg-sec-body .lg-note.warn{border-left-color:var(--amber)}

/* At-a-glance cards */
.lg-highlights{display:grid;grid-template-columns:repeat(4,1fr);gap:13px;margin:26px 0 34px}
/* Same again: a callout inside the document card, so it is a surface, not a
   frame. Nothing here is clickable, so it never takes a border at all. */
.lg-hl{background:var(--blue-tint);border:0;border-radius:14px;padding:16px}
.lg-hl-ic{display:inline-flex;width:34px;height:34px;border-radius:10px;background:var(--blue-wash);
  color:var(--blue);align-items:center;justify-content:center;margin-bottom:11px}
.lg-hl h2{font-size:14.5px;font-weight:700;letter-spacing:-.012em;line-height:1.3;
  color:var(--ink);margin:0 0 6px;text-transform:none}
.lg-hl p{font-size:12.5px;line-height:1.55;color:var(--slate);margin:0}

/* Numbered sections */
/* A rule at the head of each one. Inside the old card the sections could be
   separated by space alone, because the card's edge held the document together.
   On the open page that space just read as a gap, so the line does the dividing
   and the gap can be smaller: 22px either side of a rule separates far more
   clearly than 34px of nothing. */
.lg-sec{margin-top:22px;padding-top:22px;border-top:1px solid var(--line);
  scroll-margin-top:calc(var(--nav-h) + 24px)}
/* The block above it already ends with its own space. */
.lg-sec:first-of-type{margin-top:0}
.lg-sec h2{display:flex;align-items:center;gap:12px;font-size:20px;letter-spacing:-.015em;
  line-height:1.3;color:var(--ink);margin:0 0 14px}
.lg-num{display:inline-flex;align-items:center;justify-content:center;min-width:28px;height:24px;
  border-radius:7px;background:var(--blue-wash);color:var(--blue);font-family:var(--mono);
  font-size:11px;font-weight:700;letter-spacing:.04em;flex-shrink:0;font-variant-numeric:tabular-nums}
.lg-anchor{color:inherit;text-decoration:none}
.lg-anchor:hover{color:var(--blue)}

/* Prose stays at a readable measure however wide the card gets. The card is
   allowed to be wide; the sentences are not. */
.lg-intro,.lg-sec-body{max-width:88ch}
.lg-sec-body{padding-left:40px}
.lg-sec-body p{font-size:15.5px;line-height:1.72;color:var(--ink-soft);margin:0 0 14px}
.lg-sec-body p:last-child{margin-bottom:0}
.lg-sec-body h3{font-size:16px;font-weight:700;letter-spacing:-.01em;color:var(--ink);margin:22px 0 10px}
.lg-sec-body a{color:var(--blue);font-weight:600;text-decoration:none}
.lg-sec-body a:hover{text-decoration:underline}
.lg-sec-body strong{color:var(--ink);font-weight:670}
.lg-sec-body ul:not(.lg-yes):not(.lg-no){margin:0 0 14px;padding-left:22px;list-style:disc}
.lg-sec-body ul:not(.lg-yes):not(.lg-no) li{font-size:15.5px;line-height:1.7;color:var(--ink-soft);margin-bottom:8px}

/* Permitted / prohibited lists */
.lg-yes,.lg-no{list-style:none;margin:0 0 16px;padding:0;display:flex;flex-direction:column;gap:9px}
.lg-yes li,.lg-no li{position:relative;padding-left:29px;font-size:15px;line-height:1.6;color:var(--ink-soft)}
.lg-yes li::before,.lg-no li::before{position:absolute;left:0;top:1px;width:19px;height:19px;
  border-radius:6px;display:flex;align-items:center;justify-content:center;font-size:12px;
  font-weight:700;line-height:1}
.lg-yes li::before{content:"\2713";background:var(--green-wash);color:#0a7a56}
.lg-no li::before{content:"\2715";background:#fdecec;color:#c53434}

/* Contact cards */
.lg-contact{display:grid;grid-template-columns:repeat(2,1fr);gap:13px;margin-top:16px}
/* Tinted for the same reason as the Read next cards below: inside the document
   card, an outline was a frame inside a frame. */
.lg-contact-card{display:flex;align-items:center;gap:13px;background:var(--blue-tint);
  border:1px solid transparent;border-radius:13px;padding:15px 17px;text-decoration:none;
  transition:border-color .15s,background .15s,transform .15s}
.lg-contact-card:hover{background:#fff;border-color:var(--blue);transform:translateY(-2px)}
.lg-contact-ic{display:flex;width:36px;height:36px;border-radius:10px;background:var(--blue-wash);
  color:var(--blue);align-items:center;justify-content:center;flex-shrink:0}
.lg-contact-t{display:flex;flex-direction:column;gap:2px;min-width:0}
.lg-contact-l{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--slate-light)}
.lg-contact-v{font-size:14.5px;font-weight:650;color:var(--ink)}

/* Read next */
.lg-related{margin-top:40px;padding-top:28px;border-top:1px solid var(--line)}
.lg-related>h2{font-size:19px;letter-spacing:-.015em;margin:0 0 15px}
.lg-related-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:13px}
/* Tinted, not outlined. These sit inside the document card, so a white card with
   a grey border on a white ground was a frame drawn inside a frame. The tint
   makes them read as a distinct surface; the border arrives on hover, where it
   is doing real work by showing what you are about to click. */
.lg-related-card{display:flex;flex-direction:column;gap:6px;background:var(--blue-tint);
  border:1px solid transparent;border-radius:13px;padding:16px 18px;text-decoration:none;
  transition:border-color .15s,background .15s,transform .15s,box-shadow .15s}
.lg-related-card:hover{background:#fff;border-color:var(--blue);transform:translateY(-2px);
  box-shadow:var(--shadow)}
.lg-related-t{font-size:14.5px;font-weight:650;color:var(--ink);line-height:1.35}
.lg-related-s{font-size:12.5px;color:var(--slate);line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}

/* ── Responsive ── */
@media(max-width:1100px){
  .lg-layout{grid-template-columns:1fr;gap:20px}
  .lg-side{position:static;order:2;flex-direction:row;flex-wrap:wrap}
  .lg-side-box{flex:1;min-width:260px}
  .lg-doc{order:1}
  .lg-highlights{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:640px){
  .lg-wrap{padding:20px 0 44px}
  /* No card to pad any more, so the document keeps the page's own gutter. */
  .lg-doc{padding:2px 0 0}
  .lg-doc h1{font-size:26px}
  .lg-intro p{font-size:15px}
  .lg-highlights{grid-template-columns:1fr;gap:11px}
  .lg-sec{margin-top:18px;padding-top:18px}
  .lg-sec h2{font-size:18px;gap:10px}
  /* Indenting under the number wastes too much width on a phone. */
  .lg-sec-body{padding-left:0}
  .lg-sec-body p,.lg-sec-body ul:not(.lg-yes):not(.lg-no) li{font-size:15px}
  .lg-yes li,.lg-no li{font-size:14.5px}
  .lg-contact{grid-template-columns:1fr}
  .lg-side{flex-direction:column}
  .lg-side-box{min-width:0}
}

/* A cross-reference to a policy that is not published yet. Reads as emphasis
   rather than a broken link, and becomes a real link the moment that policy is
   added to lib/legal.js. */
.lg-pending{color:var(--ink);font-weight:600;border-bottom:1px dotted var(--slate-light)}

/* ═══════════════════════════════════════════════════════════
   WHY SELL WITH US  (/why-sell-here)
   The argument page. /sell stays the short funnel.
   Numbers come from lib/levels.js, never hardcoded here.
   ═══════════════════════════════════════════════════════════ */

.ws-hero{background:linear-gradient(180deg,var(--blue-tint) 0%,#fff 100%);
  border-bottom:1px solid var(--line-soft);padding:0}
.ws-hero-in{display:grid;grid-template-columns:1fr 380px;gap:48px;align-items:center;padding:62px 0 70px}
.ws-hero-copy h1{font-size:47px;line-height:1.06;letter-spacing:-.03em;margin:20px 0 16px;max-width:15ch}
.ws-hero-copy h1 .dot{color:var(--blue)}
.ws-hero-copy>p{font-size:17px;line-height:1.62;color:var(--slate);margin:0;max-width:52ch}
.ws-hero-copy>p strong{color:var(--ink);font-weight:700}

.ws-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:26px}
.ws-cta .btn{padding:14px 26px}

.ws-facts{list-style:none;display:flex;flex-wrap:wrap;gap:34px;margin:32px 0 0;padding:26px 0 0;
  border-top:1px solid var(--line)}
.ws-facts li{display:flex;flex-direction:column;gap:3px}
.ws-facts strong{font-size:21px;font-weight:750;letter-spacing:-.02em;color:var(--ink)}
.ws-facts span{font-size:12.5px;color:var(--slate-light)}

/* Hero art: a small dashboard with the ladder rising behind it. */
.ws-hero-art{position:relative;height:290px}
.ws-art-panel{position:absolute;inset:14px 0 0 0;background:#fff;border:1px solid var(--line);
  border-radius:18px;box-shadow:var(--shadow);padding:20px;display:flex;flex-direction:column;gap:13px}
.ws-art-row{display:flex;align-items:center;gap:12px}
.ws-art-l{flex:1;height:9px;border-radius:5px;background:var(--line-soft)}
.ws-art-v{width:52px;height:9px;border-radius:5px;background:var(--line-soft)}
.ws-art-v.on{background:var(--blue)}
.ws-art-bars{margin-top:auto;display:flex;align-items:flex-end;gap:10px;height:110px}
.ws-art-bars span{flex:1;border-radius:7px 7px 0 0;background:var(--blue-wash)}
.ws-art-chip{position:absolute;right:-14px;bottom:6px;width:52px;height:52px;border-radius:16px;
  background:var(--blue);color:#fff;display:flex;align-items:center;justify-content:center;
  box-shadow:0 12px 30px rgba(31,82,255,.34)}

/* Section shell */
.ws-sec{padding:70px 0}
.ws-sec.band{background:var(--blue-tint);border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft)}
.ws-head{max-width:60ch;margin:0 0 34px}
.ws-eyebrow{display:inline-block;font-family:var(--mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:var(--blue);margin-bottom:12px}
.ws-head h2{font-size:32px;letter-spacing:-.026em;line-height:1.18;margin:0 0 12px}
.ws-head p{font-size:16px;line-height:1.65;color:var(--slate);margin:0}

/* The ladder of take-home figures */
.ws-ladder{display:grid;grid-template-columns:repeat(5,1fr);gap:14px}
.ws-rung{background:#fff;border:1px solid var(--line);border-radius:16px;padding:20px;
  display:flex;flex-direction:column;gap:11px;transition:border-color .16s,transform .16s,box-shadow .16s}
.ws-rung:hover{border-color:#d6dbe8;transform:translateY(-2px);box-shadow:var(--shadow)}
.ws-rung.best{border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-wash)}
.ws-rung-top{display:flex;align-items:baseline;justify-content:space-between;gap:8px}
.ws-rung-name{font-size:13px;font-weight:700;color:var(--ink);line-height:1.3}
.ws-rung-fee{font-size:11px;font-weight:600;color:var(--slate-light);flex-shrink:0}
.ws-rung-amount{font-size:27px;font-weight:750;letter-spacing:-.028em;color:var(--ink);
  font-variant-numeric:tabular-nums}
.ws-rung.best .ws-rung-amount{color:var(--blue)}
.ws-rung-bar{height:6px;border-radius:4px;background:var(--line-soft);overflow:hidden}
.ws-rung-bar span{display:block;height:100%;border-radius:4px;background:var(--blue-wash)}
.ws-rung.best .ws-rung-bar span{background:var(--blue)}
.ws-rung-foot{font-size:11.5px;color:var(--slate-light);margin-top:auto}

.ws-note{display:flex;gap:13px;background:var(--blue-wash);border:1px solid #dbe3ff;
  border-radius:14px;padding:18px 20px;margin-top:22px}
.ws-note svg{color:var(--blue);flex-shrink:0;margin-top:2px}
.ws-note p{font-size:14.5px;line-height:1.65;color:var(--ink-soft);margin:0}
.ws-note strong{color:var(--ink);font-weight:670}

/* Feature cards */
.ws-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.ws-card{background:#fff;border:1px solid var(--line);border-radius:17px;padding:24px;
  display:flex;flex-direction:column;transition:border-color .16s,transform .16s,box-shadow .16s}
.ws-card:hover{border-color:#d6dbe8;transform:translateY(-2px);box-shadow:var(--shadow)}
.ws-card-ic{width:42px;height:42px;border-radius:12px;background:var(--blue-wash);color:var(--blue);
  display:flex;align-items:center;justify-content:center;margin-bottom:15px}
.ws-card h3{font-size:17px;letter-spacing:-.014em;line-height:1.3;margin:0 0 9px}
.ws-card p{font-size:14.5px;line-height:1.62;color:var(--slate);margin:0 0 14px}
.ws-link{margin-top:auto;font-size:13.5px;font-weight:700;color:var(--blue);text-decoration:none}
.ws-link span{display:inline-block;transition:margin-left .15s}
.ws-link:hover span{margin-left:3px}

/* Honest section */
.ws-honest{display:grid;grid-template-columns:repeat(2,1fr);gap:20px}
.ws-honest-item{display:flex;gap:15px;background:#fff;border:1px solid var(--line);
  border-radius:16px;padding:22px}
.ws-honest-ic{width:34px;height:34px;border-radius:10px;background:var(--green-wash);color:#0a7a56;
  display:flex;align-items:center;justify-content:center;flex-shrink:0}
.ws-honest-ic.warn{background:#fff2dc;color:#b06f05}
.ws-honest-item h3{font-size:16px;letter-spacing:-.012em;line-height:1.32;margin:0 0 7px}
.ws-honest-item p{font-size:14.5px;line-height:1.62;color:var(--slate);margin:0}

/* FAQ */
.ws-faq{background:#fff;border:1px solid var(--line);border-radius:17px;overflow:hidden;
  box-shadow:var(--shadow)}
.ws-q{border-bottom:1px solid var(--line-soft)}
.ws-q:last-child{border-bottom:0}
.ws-q summary{display:flex;align-items:center;gap:16px;padding:19px 24px;cursor:pointer;
  list-style:none;transition:background .13s}
.ws-q summary::-webkit-details-marker{display:none}
.ws-q summary:hover{background:var(--blue-tint)}
.ws-q summary:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
.ws-q summary h3{flex:1;font-size:16px;font-weight:650;letter-spacing:-.01em;line-height:1.4;margin:0}
.ws-q-mark{position:relative;width:13px;height:13px;flex-shrink:0}
.ws-q-mark::before,.ws-q-mark::after{content:"";position:absolute;background:var(--slate-light);
  border-radius:2px;transition:transform .22s cubic-bezier(.22,.8,.28,1),background .13s}
.ws-q-mark::before{top:5.5px;left:0;width:13px;height:2px}
.ws-q-mark::after{top:0;left:5.5px;width:2px;height:13px}
.ws-q[open] .ws-q-mark::after{transform:rotate(90deg)}
.ws-q[open] .ws-q-mark::before,.ws-q[open] .ws-q-mark::after{background:var(--blue)}
.ws-q-body{padding:0 24px 22px;max-width:74ch}
.ws-q-body p{font-size:15px;line-height:1.7;color:var(--ink-soft);margin:0 0 12px}
.ws-q-body p:last-child{margin-bottom:0}
.ws-q-body a{color:var(--blue);font-weight:600;text-decoration:none}
.ws-q-body a:hover{text-decoration:underline}

/* Closing CTA */

/* ── Responsive ── */
@media(max-width:1100px){
  .ws-hero-in{grid-template-columns:1fr;gap:36px;padding:48px 0 54px}
  .ws-hero-art{display:none}
  .ws-hero-copy h1{font-size:38px}
  .ws-ladder{grid-template-columns:repeat(3,1fr)}
  .ws-grid{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:760px){
  .ws-ladder{grid-template-columns:repeat(2,1fr)}
  .ws-honest{grid-template-columns:1fr}
}
@media(max-width:640px){
  .ws-hero-in{padding:38px 0 44px}
  .ws-hero-copy h1{font-size:31px;max-width:none}
  .ws-hero-copy>p{font-size:15.5px}
  .ws-facts{gap:20px 28px;margin-top:26px;padding-top:22px}
  .ws-facts strong{font-size:18px}
  .ws-sec{padding:48px 0}
  .ws-head h2{font-size:25px}
  .ws-head p{font-size:15px}
  .ws-ladder{grid-template-columns:1fr;gap:11px}
  .ws-rung{flex-direction:row;align-items:center;gap:14px;flex-wrap:wrap;padding:16px 18px}
  .ws-rung-top{flex:1;min-width:130px;flex-direction:column;align-items:flex-start;gap:2px}
  .ws-rung-amount{font-size:22px}
  .ws-rung-bar{flex-basis:100%;order:3}
  .ws-rung-foot{flex-basis:100%;order:4;margin-top:0}
  .ws-grid{grid-template-columns:1fr;gap:14px}
  .ws-q summary{padding:16px 17px;gap:12px}
  .ws-q summary h3{font-size:15px}
  .ws-q-body{padding:0 17px 19px}
}

/* ═══════════════════════════════════════════════════════════
   AUTH PAGES  (/login, /register, /forgot-password, ...)
   These now carry the real navbar and footer, with the same
   two-part panel the header dialog uses. Desktop only: below
   900px it falls back to the plain centred card it always was.
   ═══════════════════════════════════════════════════════════ */

.auth-page .site-main{background:var(--blue-tint)}
.authp-wrap{padding:32px 0 46px}
/* Same 820px and same 1fr 1fr split as .authm, so the page is the dialog with a
   header and footer around it rather than a wider relative of it. */
.authp-card{display:grid;grid-template-columns:1fr 1fr;max-width:820px;margin:0 auto;
  background:#fff;border:1px solid var(--line);border-radius:20px;overflow:hidden;
  box-shadow:0 20px 60px rgba(10,17,48,.13)}
/* Same padding as .authm-pane, so the form sits in the pane exactly as it does
   in the dialog. The dialog's overflow and max-height are not shared: a page
   scrolls on its own. */
.authp-pane{padding:30px 28px 26px;min-width:0;background:#fff;position:relative;z-index:1;
  display:flex;flex-direction:column;justify-content:center}
/* Matching the dialog: the brand panel beside the form already carries the mark,
   so the pane's own logo only appears once that panel is dropped. */
.authp-pane .auth-logo.sm{display:none;align-self:center;margin-bottom:16px}
.authp-pane .auth-logo.sm .auth-logo-img{height:30px}
/* The page's own extras, kept but sized to the dialog's scale. */
.authp-pane .auth-info{margin-top:0;margin-bottom:14px;text-align:center;padding:9px 13px;font-size:12px;line-height:1.45}
.authp-pane .auth-head h1{margin:0}

/* The aside itself comes entirely from the shared .authm rules above, so the
   panel is identical in the dialog and on the page. Only the image clamp is
   page-specific, because the page renders at a wider range of widths. */
/* Clamp width only. `height:auto` here let the aside's mark scale up to the
   column width instead of holding its 46px, making it far larger than the
   dialog's. */
.authp-card .auth-aside .auth-logo-img{max-width:100%}

/* Tablets keep the two-panel card. The breakpoint is 760px to match the dialog
   exactly, so the page and the popup drop the brand panel at the same width
   rather than at two different ones. */
@media(max-width:1000px) and (min-width:761px){
  /* The panel is narrower here, so its own padding comes in to suit. */
  .authp-card .auth-aside-in{padding:28px 24px}
  .authp-card .auth-aside-in h2{font-size:22px;margin:16px 0 10px}
  .authp-card .auth-aside-in p{font-size:13px}
  .authp-card .auth-aside-list li{font-size:12.5px}
  .authp-pane{padding:28px 24px 24px}
}
@media(max-width:760px){
  /* Phone only: panel dropped rather than squeezed, as the dialog does. */
  .authp-wrap{padding:26px 0 40px}
  .authp-card{grid-template-columns:1fr;max-width:410px;border-radius:18px}
  .authp-card .auth-aside{display:none}
  .authp-pane{padding:28px 22px 26px}
  /* Panel gone, so the pane carries the mark, exactly as the dialog does. */
  .authp-pane .auth-logo.sm{display:flex}
}

/* ═══════════════════════════════════════════════════════════
   SUPPORT  (/support)
   ═══════════════════════════════════════════════════════════ */

.sp-hero{background:var(--blue-tint);border-bottom:1px solid var(--line-soft);padding:30px 0 36px}
.sp-hero-in{display:flex;align-items:flex-end;justify-content:space-between;gap:36px;flex-wrap:wrap}
.sp-hero h1{font-size:34px;letter-spacing:-.026em;line-height:1.15;margin:0 0 10px}
.sp-hero h1 .dot{color:var(--blue)}
.sp-hero-in>div>p{font-size:15.5px;line-height:1.62;color:var(--slate);margin:0;max-width:56ch}

.sp-hero-help{display:flex;align-items:center;gap:13px;background:#fff;border:1px solid var(--line);
  border-radius:14px;padding:14px 18px;text-decoration:none;max-width:390px;
  transition:border-color .15s,transform .15s,box-shadow .15s}
.sp-hero-help:hover{border-color:var(--blue);transform:translateY(-2px);box-shadow:var(--shadow)}
.sp-hero-help-ic{width:38px;height:38px;border-radius:11px;background:var(--blue-wash);color:var(--blue);
  display:flex;align-items:center;justify-content:center;flex-shrink:0}
.sp-hero-help strong{display:block;font-size:14.5px;color:var(--ink);line-height:1.35}
.sp-hero-help em{display:block;font-style:normal;font-size:12.5px;color:var(--slate);line-height:1.45;margin-top:2px}
.sp-hero-help-go{color:var(--line);font-size:17px;flex-shrink:0;transition:color .13s,transform .16s}
.sp-hero-help:hover .sp-hero-help-go{color:var(--blue);transform:translateX(3px)}

.sp-body{padding:40px 0 64px}
.sp-layout{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:32px;align-items:start}
.sp-main{min-width:0}

/* Signed-out gate, and the sent confirmation, share a look */
.sp-gate,.sp-done{background:#fff;border:1px solid var(--line);border-radius:18px;
  padding:40px 34px;text-align:center;box-shadow:var(--shadow)}
.sp-gate-ic,.sp-done-ic{width:54px;height:54px;border-radius:16px;background:var(--blue-wash);
  color:var(--blue);display:inline-flex;align-items:center;justify-content:center;margin-bottom:16px}
.sp-done-ic{background:var(--green-wash);color:#0a7a56}
.sp-gate h2,.sp-done h2{font-size:22px;letter-spacing:-.018em;margin:0 0 10px}
.sp-gate p,.sp-done p{font-size:15px;line-height:1.65;color:var(--slate);margin:0 auto 22px;max-width:46ch}
.sp-done strong{color:var(--ink);font-family:var(--mono);font-size:14px}
.sp-gate-cta{display:flex;gap:11px;justify-content:center;flex-wrap:wrap}

/* The form */
.sp-form{background:#fff;border:1px solid var(--line);border-radius:18px;padding:30px 32px 32px;
  box-shadow:var(--shadow)}
.sp-row{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
.sp-form .auth-field{margin-bottom:20px}
.sp-textarea{resize:vertical;min-height:150px;line-height:1.6;font-family:var(--sans)}
.sp-hint{font-size:12.5px;color:var(--slate-light);margin:7px 0 0}
.sp-hint .short{color:var(--amber);font-weight:700}
.sp-actions{display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding-top:6px;
  border-top:1px solid var(--line-soft);margin-top:4px}
.sp-actions .btn{padding:13px 30px;margin-top:18px}
.sp-actions-note{font-size:12.5px;color:var(--slate-light);margin-top:18px}

/* Flat variant, used on /report. There the questions are answered with tiles
   that are already outlined boxes, so a card around them read as a frame inside
   a frame. Without it the questions sit straight on the page and the only
   outlined things left are the things you actually click. */
.sp-form-flat{background:none;border:0;border-radius:0;padding:0;box-shadow:none}
.sp-form-flat>.auth-field,.sp-form-flat>fieldset{margin-bottom:26px}
/* The labels are now section headings rather than field captions, so they carry
   a little more weight to hold the page together on their own. */
.sp-form-flat>.auth-field>.auth-label,.sp-form-flat>fieldset>legend{font-size:15px;font-weight:700;
  color:var(--ink);margin-bottom:10px}

/* Sidebar */
.sp-side{position:sticky;top:calc(var(--nav-h) + 16px);display:flex;flex-direction:column;gap:16px}
.sp-box{background:#fff;border:1px solid var(--line);border-radius:15px;padding:18px 20px}
.sp-box h2{display:flex;align-items:center;gap:9px;font-size:12.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.06em;color:var(--slate);margin:0 0 10px}
.sp-box h2 svg{color:var(--blue)}
.sp-box ul{list-style:none;margin:0;padding:0}
.sp-box li{border-bottom:1px solid var(--line-soft)}
.sp-box li:last-child{border-bottom:0}
.sp-box li a{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 0;
  font-size:13.5px;line-height:1.45;color:var(--ink-soft);text-decoration:none;transition:color .13s}
.sp-box li a:hover{color:var(--blue)}
.sp-box li a svg{color:var(--line);flex-shrink:0;transition:color .13s,transform .13s}
.sp-box li a:hover svg{color:var(--blue);transform:translateX(2px)}
.sp-box-tip p{font-size:13.5px;line-height:1.6;color:var(--slate);margin:0 0 11px}
.sp-box-tip p:last-child{margin-bottom:0}
.sp-box-tip strong{color:var(--ink);font-weight:650}
.sp-box-tip a{color:var(--blue);font-weight:600;text-decoration:none}

@media(max-width:1000px){
  .sp-layout{grid-template-columns:1fr;gap:24px}
  .sp-side{position:static;order:2}
  .sp-main{order:1}
  .sp-hero-help{max-width:none;width:100%}
}
@media(max-width:640px){
  .sp-hero{padding:22px 0 28px}
  .sp-hero h1{font-size:26px}
  .sp-body{padding:26px 0 46px}
  .sp-form{padding:22px 18px 24px;border-radius:16px}
  /* The flat form has no card to pad, so it keeps the page's own gutter. */
  .sp-form-flat{padding:0}
  .sp-form-flat>.auth-field,.sp-form-flat>fieldset{margin-bottom:22px}
  .sp-form-flat>.auth-field>.auth-label,.sp-form-flat>fieldset>legend{font-size:14.5px}
  .sp-row{grid-template-columns:1fr;gap:0}
  .sp-gate,.sp-done{padding:30px 20px}
  .sp-actions{flex-direction:column;align-items:stretch}
  .sp-actions-note{margin-top:10px;text-align:center}
}

/* Without the floating CTA card there is nothing pulling the footer up, so it
   needs its own top padding instead of the negative margin the card supplies. */
.foot-flush{padding-top:56px}

/* Space under a form-level message, which otherwise sat flush against the first
   field label. */
.sp-form .auth-error,.sp-form .auth-ok{margin-bottom:20px}

/* ═══════════════════════════════════════════════════════════
   SELLER GUIDE  (/sell/guide)
   Long-form, read in order the first time and returned to one
   chapter at a time later, hence the sticky contents list.
   ═══════════════════════════════════════════════════════════ */

.sg-hero{background:var(--blue-tint);border-bottom:1px solid var(--line-soft);padding:30px 0 38px}
.sg-hero-in{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:40px;align-items:center}
.sg-hero h1{font-size:36px;letter-spacing:-.028em;line-height:1.13;margin:0 0 12px}
.sg-hero h1 .dot{color:var(--blue)}
.sg-hero-copy>p{font-size:16px;line-height:1.62;color:var(--slate);margin:0;max-width:56ch}
.sg-hero-meta{display:flex;gap:22px;flex-wrap:wrap;margin-top:16px}
.sg-hero-meta span{display:inline-flex;align-items:center;gap:7px;font-size:13px;color:var(--slate-light)}
.sg-hero-meta svg{color:var(--blue)}
.sg-hero-cta{flex-shrink:0;padding:14px 26px;white-space:nowrap}

.sg-body{padding:44px 0 70px}
.sg-layout{display:grid;grid-template-columns:280px minmax(0,1fr);gap:40px;align-items:start}
.sg-main{min-width:0}
.sg-side{position:sticky;top:calc(var(--nav-h) + 16px);display:flex;flex-direction:column;gap:16px}

/* Contents */
.sg-toc{background:#fff;border:1px solid var(--line);border-radius:16px;padding:18px 16px}
.sg-toc h2{font-size:12.5px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  color:var(--slate);margin:0 0 8px;padding:0 8px}
.sg-toc ol{list-style:none;margin:0;padding:0;counter-reset:none}
.sg-toc a{display:flex;gap:11px;padding:9px 8px;border-radius:9px;text-decoration:none;
  transition:background .13s,color .13s}
.sg-toc a:hover{background:var(--blue-tint)}
.sg-toc-n{font-family:var(--mono);font-size:11px;font-weight:600;color:var(--blue);
  padding-top:2px;flex-shrink:0}
.sg-toc-t{font-size:13.5px;line-height:1.42;color:var(--ink-soft)}
.sg-toc a:hover .sg-toc-t{color:var(--blue)}

.sg-side-box{background:#fff;border:1px solid var(--line);border-radius:16px;padding:18px 20px}
.sg-side-box h2{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.06em;color:var(--slate);margin:0 0 10px}
.sg-side-box h2 svg{color:var(--blue)}
.sg-side-box>p{font-size:13px;line-height:1.6;color:var(--slate);margin:0 0 12px}
.sg-side-box ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.sg-side-box li a{font-size:13.5px;font-weight:600;color:var(--blue);text-decoration:none}
.sg-side-box li a:hover{text-decoration:underline}

/* Chapters */
.sg-chapter{background:#fff;border:1px solid var(--line);border-radius:18px;
  padding:30px 34px 34px;margin-bottom:20px}
.sg-ch-head{display:flex;gap:16px;align-items:flex-start;padding-bottom:18px;margin-bottom:20px;
  border-bottom:1px solid var(--line-soft)}
.sg-ch-n{font-family:var(--mono);font-size:13px;font-weight:700;color:var(--blue);
  background:var(--blue-wash);border-radius:9px;padding:7px 10px;flex-shrink:0;line-height:1}
.sg-ch-head h2{font-size:24px;letter-spacing:-.02em;line-height:1.22;margin:0 0 5px}
.sg-ch-time{font-size:12.5px;color:var(--slate-light)}

.sg-ch-body{max-width:76ch}
.sg-ch-body p{font-size:15.5px;line-height:1.72;color:var(--ink-soft);margin:0 0 15px}
.sg-ch-body p:last-child{margin-bottom:0}
.sg-ch-body h3{font-size:16.5px;letter-spacing:-.012em;margin:26px 0 10px;color:var(--ink)}
.sg-ch-body h3:first-child{margin-top:0}
.sg-ch-body strong{color:var(--ink);font-weight:670}
.sg-ch-body em{font-style:italic}
.sg-ch-body a{color:var(--blue);font-weight:600;text-decoration:none}
.sg-ch-body a:hover{text-decoration:underline}

/* Checklists inside a chapter */
.sg-check{list-style:none;margin:0 0 15px;padding:0;display:flex;flex-direction:column;gap:9px}
.sg-check li{position:relative;padding-left:29px;font-size:15px;line-height:1.6;color:var(--ink-soft)}
.sg-check li::before{content:"";position:absolute;left:0;top:4px;width:19px;height:19px;
  border-radius:6px;background:var(--green-wash)}
.sg-check li::after{content:"";position:absolute;left:6px;top:9px;width:6px;height:10px;
  border:solid #0a7a56;border-width:0 2px 2px 0;transform:rotate(45deg)}

/* Callouts */
/* Numbered steps in the seller guide, where the order genuinely carries the
   meaning: get the id, then zip, then upload. A tick list would lose that. */
.sg-steps{margin:0 0 15px;padding:0 0 0 4px;list-style:none;counter-reset:sgstep;
  display:flex;flex-direction:column;gap:9px}
.sg-steps li{position:relative;padding-left:34px;font-size:15px;line-height:1.6;color:var(--ink-soft)}
.sg-steps li::before{counter-increment:sgstep;content:counter(sgstep);position:absolute;left:0;top:1px;
  width:22px;height:22px;border-radius:50%;background:var(--blue-wash);color:var(--blue);
  font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center}

.sg-callout{display:flex;gap:12px;background:var(--blue-wash);border:1px solid #dbe3ff;
  border-left:3px solid var(--blue);border-radius:12px;padding:16px 18px;margin:20px 0}
.sg-callout.warn{background:#fff8ec;border-color:#f5dcaf;border-left-color:var(--amber)}
.sg-callout p{font-size:14.5px;line-height:1.65;color:var(--ink-soft);margin:0}

/* Closing note. Not a CTA band: the footer card is the ask on selling pages, and
   a second band stacked above it is the thing we keep having to undo. */
.sg-end{border-left:3px solid var(--blue);background:var(--blue-tint);border-radius:0 12px 12px 0;
  padding:20px 24px;margin-top:6px}
.sg-end p{font-size:15px;line-height:1.68;color:var(--ink-soft);margin:0;max-width:70ch}

@media(max-width:1000px){
  .sg-layout{grid-template-columns:1fr;gap:24px}
  .sg-side{position:static}
  .sg-toc ol{display:grid;grid-template-columns:repeat(2,1fr);gap:2px}
}
@media(max-width:640px){
  .sg-hero{padding:22px 0 28px}
  .sg-hero h1{font-size:27px}
  .sg-hero-in>div>p{font-size:15px}
  .sg-body{padding:28px 0 50px}
  .sg-toc ol{grid-template-columns:1fr}
  .sg-chapter{padding:22px 18px 24px;border-radius:15px}
  .sg-ch-head{gap:12px}
  .sg-ch-head h2{font-size:20px}
  .sg-ch-body p,.sg-check li{font-size:15px}
  .sg-end{padding:17px 18px}
}

/* ── Report an item (/report) ────────────────────────────────
   Shares the support page's shell; these are the report-only parts. */
.sp-gate-extra{font-size:13.5px;color:var(--slate-light)}

.rp-reasons{border:0;padding:0;margin:0 0 22px;display:flex;flex-direction:column;gap:9px}
.rp-reasons legend{padding:0;margin-bottom:11px}
.rp-reason{display:block;cursor:pointer}
/* Visually hidden rather than display:none, so the radio stays focusable and
   arrow keys still move between the options. */
.rp-reason input{position:absolute;opacity:0;width:1px;height:1px;pointer-events:none}
.rp-reason-body{display:flex;gap:13px;align-items:flex-start;border:1px solid var(--line);
  border-radius:13px;padding:14px 16px;transition:border-color .14s,background .14s,box-shadow .14s}
.rp-reason:hover .rp-reason-body{border-color:#cbd4e6;background:var(--blue-tint)}
.rp-reason input:checked+.rp-reason-body{border-color:var(--blue);background:var(--blue-wash);
  box-shadow:0 0 0 3px rgba(31,82,255,.09)}
.rp-reason input:focus-visible+.rp-reason-body{outline:2px solid var(--blue);outline-offset:2px}
.rp-reason-ic{width:34px;height:34px;border-radius:10px;background:#fff;border:1px solid var(--line);
  color:var(--slate-light);display:flex;align-items:center;justify-content:center;flex-shrink:0;
  transition:color .14s,border-color .14s}
.rp-reason input:checked+.rp-reason-body .rp-reason-ic{color:var(--blue);border-color:#c6d2ff}
.rp-reason-body strong{display:block;font-size:14.5px;color:var(--ink);line-height:1.35}
.rp-reason-body em{display:block;font-style:normal;font-size:13px;color:var(--slate);
  line-height:1.5;margin-top:3px}

/* The copyright declarations. Amber rather than blue: this is the part with
   legal weight, and it should not read like another form field. */
.rp-legal{background:#fff8ec;border:1px solid #f5dcaf;border-radius:14px;padding:18px 20px;
  margin:0 0 22px}
.rp-legal h3{display:flex;align-items:center;gap:9px;font-size:12.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;color:#8a5a04;margin:0 0 13px}
.rp-legal h3 svg{color:var(--amber)}
.rp-declare{display:flex;gap:11px;align-items:flex-start;font-size:14px;line-height:1.6;
  color:var(--ink-soft);margin-bottom:11px;cursor:pointer}
.rp-declare input{width:17px;height:17px;margin:2px 0 0;flex-shrink:0;accent-color:var(--blue);cursor:pointer}
.rp-legal-note{font-size:12.5px;line-height:1.6;color:#8a5a04;margin:13px 0 0;
  padding-top:12px;border-top:1px solid #f0d9a8}

@media(max-width:640px){
  .rp-reason-body{padding:12px 13px;gap:11px}
  .rp-legal{padding:15px 16px}
}

/* ── Contact (/contact) ──────────────────────────────────────
   Route cards above, general enquiry form below in the shared
   support shell. */
.ct-routes{padding:44px 0 8px}
.ct-h2{font-size:22px;letter-spacing:-.018em;margin:0 0 8px}
.ct-lede{font-size:15px;line-height:1.65;color:var(--slate);margin:0 0 24px;max-width:70ch}
.ct-lede a{color:var(--blue);font-weight:600;text-decoration:none}
.ct-routes .ct-h2{margin-bottom:20px}

.ct-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.ct-card{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);
  border-radius:16px;padding:20px;text-decoration:none;
  transition:border-color .15s,transform .15s,box-shadow .15s}
.ct-card:hover{border-color:var(--blue);transform:translateY(-2px);box-shadow:var(--shadow)}
.ct-card-ic{width:40px;height:40px;border-radius:11px;background:var(--blue-wash);color:var(--blue);
  display:flex;align-items:center;justify-content:center;margin-bottom:14px}
.ct-card h3{font-size:15.5px;letter-spacing:-.012em;line-height:1.32;margin:0 0 7px;color:var(--ink)}
.ct-card p{font-size:13.5px;line-height:1.58;color:var(--slate);margin:0 0 14px}
.ct-card-go{margin-top:auto;font-size:13px;font-weight:700;color:var(--blue)}
.ct-card-go span{display:inline-block;transition:margin-left .15s}
.ct-card:hover .ct-card-go span{margin-left:3px}

/* The form sits in the same shell as support, so it needs the section's own
   top spacing trimmed where it follows the route cards. */
.ct-routes + .sp-body{padding-top:34px}

@media(max-width:1000px){
  .ct-grid{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:640px){
  .ct-routes{padding:28px 0 4px}
  .ct-grid{grid-template-columns:1fr;gap:12px}
  .ct-card{padding:17px}
  .ct-h2{font-size:19px}
  .ct-routes + .sp-body{padding-top:26px}
}

/* ── About (/about) ──────────────────────────────────────────
   Statement page. No metrics, so the visual weight sits on the
   typography and the numbered problem list rather than stats. */
.ab-hero{background:var(--blue-tint);border-bottom:1px solid var(--line-soft);padding:32px 0 46px}
/* The art column is sized so the illustration stays shorter than the copy beside
   it. At 420px it was 355px tall against 293px of copy, so it was the art, not
   the words, setting the hero height and adding 62px of it. */
.ab-hero-in{display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:44px;align-items:center}
.ab-hero h1{font-size:42px;letter-spacing:-.03em;line-height:1.1;margin:0 0 18px;
  max-width:20ch;text-wrap:balance}
.ab-hero h1 .dot{color:var(--blue)}
.ab-hero-copy>p{font-size:16.5px;line-height:1.66;color:var(--slate);margin:0;max-width:58ch}
.ab-hero-art{display:flex;justify-content:center}
.ab-hero-art img{width:100%;max-width:320px;height:auto;display:block}
@media(max-width:1180px){.ab-hero-art img{max-width:280px}}

.ab-sec{padding:62px 0}
.ab-sec.band{background:var(--blue-tint);border-top:1px solid var(--line-soft);
  border-bottom:1px solid var(--line-soft)}
.ab-head{max-width:62ch;margin:0 0 32px}
.ab-eyebrow{display:inline-block;font-family:var(--mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:var(--blue);margin-bottom:11px}
.ab-head h2{font-size:30px;letter-spacing:-.026em;line-height:1.2;margin:0 0 11px}
.ab-head>p{font-size:15.5px;line-height:1.65;color:var(--slate);margin:0}

/* What we are */
.ab-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px}
.ab-card{background:#fff;border:1px solid var(--line);border-radius:17px;padding:24px}
.ab-card-ic{width:42px;height:42px;border-radius:12px;background:var(--blue-wash);color:var(--blue);
  display:flex;align-items:center;justify-content:center;margin-bottom:15px}
.ab-card h3{font-size:17px;letter-spacing:-.014em;line-height:1.3;margin:0 0 9px}
.ab-card p{font-size:14.5px;line-height:1.65;color:var(--slate);margin:0}

/* Numbered problems. The numbers are a real sequence of four points, not
   decoration, which is the only reason they are numbered. */
.ab-problems{display:flex;flex-direction:column;gap:2px}
.ab-problem{display:flex;gap:22px;background:#fff;border:1px solid var(--line);padding:26px 28px}
.ab-problem:first-child{border-radius:16px 16px 0 0}
.ab-problem:last-child{border-radius:0 0 16px 16px}
.ab-problem + .ab-problem{border-top:0}
.ab-p-n{font-family:var(--mono);font-size:13px;font-weight:700;color:var(--blue);flex-shrink:0;
  padding-top:3px}
.ab-problem h3{font-size:18px;letter-spacing:-.016em;line-height:1.3;margin:0 0 9px}
.ab-problem p{font-size:15px;line-height:1.68;color:var(--ink-soft);margin:0 0 12px;max-width:74ch}
.ab-link{font-size:13.5px;font-weight:700;color:var(--blue);text-decoration:none}
.ab-link span{display:inline-block;transition:margin-left .15s}
.ab-link:hover span{margin-left:3px}

/* Commitments */
.ab-commit{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:18px}
.ab-commit li{display:flex;gap:14px;background:#fff;border:1px solid var(--line);
  border-radius:15px;padding:20px 22px}
.ab-commit li:first-child{grid-column:1 / -1}
.ab-c-ic{width:30px;height:30px;border-radius:9px;background:#ffe9e9;color:#b42318;
  display:flex;align-items:center;justify-content:center;flex-shrink:0}
.ab-commit strong{display:block;font-size:15.5px;color:var(--ink);letter-spacing:-.01em;
  line-height:1.32;margin-bottom:6px}
.ab-commit p{font-size:14px;line-height:1.62;color:var(--slate);margin:0}

/* Who runs it */
.ab-who{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:44px;align-items:start}
.ab-who h2{font-size:28px;letter-spacing:-.024em;line-height:1.2;margin:0 0 14px}
.ab-who p{font-size:15.5px;line-height:1.68;color:var(--ink-soft);margin:0 0 14px;max-width:60ch}
/* Scoped to prose links only. As `.ab-who a` it also hit the buttons in
   .ab-who-cta, giving .btn-primary blue text on its blue fill so "Get in touch"
   was invisible. */
.ab-who p a{color:var(--blue);font-weight:600;text-decoration:none}
.ab-who-cta{display:flex;gap:11px;flex-wrap:wrap;margin-top:22px}
.ab-facts{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
.ab-fact{background:#fff;border:1px solid var(--line);border-radius:15px;padding:20px}
.ab-fact strong{display:block;font-size:22px;font-weight:750;letter-spacing:-.022em;
  color:var(--ink);margin-bottom:6px}
.ab-fact span{font-size:13px;line-height:1.5;color:var(--slate)}

@media(max-width:1000px){
  /* Two columns are kept well into tablet: stacking the art under the copy here
     took the hero to 661px, taller than on desktop. Beside the copy it costs no
     extra height at all. */
  .ab-hero-in{grid-template-columns:minmax(0,1fr) 240px;gap:30px}
  .ab-hero h1{font-size:34px;max-width:26ch}
  .ab-hero-art img{max-width:240px}
  .ab-grid{grid-template-columns:1fr}
  .ab-commit{grid-template-columns:1fr}
  .ab-commit li:first-child{grid-column:auto}
  .ab-who{grid-template-columns:1fr;gap:32px}
}
@media(max-width:640px){
  .ab-hero{padding:24px 0 34px}
  .ab-hero h1{font-size:28px;max-width:none}
  /* Phones: one column, and the illustration steps aside. Below the copy it added
     220px to a hero that is already the tallest thing on the screen. */
  .ab-hero-in{grid-template-columns:1fr;gap:20px;align-items:start}
  .ab-hero-art{display:none}
  .ab-hero-copy>p{font-size:15.5px}
  .ab-sec{padding:42px 0}
  .ab-head h2{font-size:23px}
  .ab-who h2{font-size:22px}
  .ab-problem{flex-direction:column;gap:10px;padding:20px 18px}
  .ab-problem h3{font-size:17px}
  .ab-facts{grid-template-columns:1fr}
}

/* ── Auth card: compressed vertical rhythm ───────────────────
   Scoped to the sign-in card, in the dialog and on the page, so the site's
   other forms (support, report, contact, dashboard) keep their own spacing. */
.authm .auth-input,.authp-pane .auth-input{padding:11px 15px}
.authm .auth-field,.authp-pane .auth-field{gap:6px}
.authm .auth-hint,.authp-pane .auth-hint{font-size:11.5px;line-height:1.4;margin-top:1px}
.authm .auth-btn,.authp-pane .auth-btn{padding:12px}
.authm .auth-2col,.authp-pane .auth-2col{gap:12px}
/* The Google block and its divider, tightened inside the sign-in card only. */
.authm .gsi,.authp-pane .gsi{margin-bottom:14px}
.authm .gsi-or,.authp-pane .gsi-or{margin-top:12px}


/* ── Full-width buttons: phones only ────────────────────────
   A stretched button reads as a bug rather than a call to action once there is
   real width to fill: the seller guide CTA was spanning the full tablet width.
   These stretch below 520px, where the bigger tap target earns it, and keep
   their natural width above. */
@media(max-width:520px){
  .hc-helpful-no .btn,
  .ws-cta .btn,
  .sp-gate-cta .btn,
  .sp-actions .btn,
  .ab-who-cta .btn,
  .pf-actions .btn,
  .author-cta,
  .sg-hero-cta{width:100%;justify-content:center;text-align:center}
}
/* The footer CTA card stacks below 820px; its button keeps its own width and
   sits under the copy rather than spanning the card, which on a tablet meant a
   button most of the viewport wide. It fills only on phones. */
@media(max-width:520px){
}

/* Between phone and desktop the purchase card spans the content width, so its
   full-width button reached ~90% of the viewport. Capped and centred in that
   range; still edge to edge on a phone where the tap target is worth it. */
@media(min-width:521px) and (max-width:900px){
  .pd-add,.pd-author .btn{max-width:460px;margin-left:auto;margin-right:auto}
}

/* Seller guide hero: ask on top, illustration beneath, both right-aligned. The
   illustration is sized to sit inside the height the copy already needs, so it
   does not push the hero taller, and it is dropped below 1000px rather than
   stacked under the copy where it only added length. */
.sg-hero-side{display:flex;flex-direction:column;align-items:flex-end;gap:16px}
.sg-hero-art{line-height:0}
.sg-hero-art img{width:210px;height:auto;display:block}
@media(max-width:1180px){.sg-hero-art img{width:186px}}
@media(max-width:1000px){.sg-hero-art img{width:170px}}
@media(max-width:860px){.sg-hero-art img{width:148px}}
@media(max-width:640px){
  /* Phones only: no room for the illustration beside the copy. */
  .sg-hero-in{grid-template-columns:1fr;gap:20px;align-items:start}
  .sg-hero-art{display:none}
}
@media(max-width:520px){
  .sg-hero-side{align-self:stretch}
}

/* The seller guide CTA now sits under the chapter count, in the copy column, at
   every width. Margin rather than the column gap so it reads as belonging to the
   copy above it. */
.sg-hero-copy .sg-hero-cta{margin-top:20px}

/* Footer CTA: copy left, button right on one line wherever that genuinely fits.
   The headline is nowrap, so below this the button and the copy fight for the
   same space and the headline gets clipped: at 390px it rendered as "Tu". Under
   660px the button drops beneath the copy, which is the only thing that fits. */
@media(min-width:661px){
  .foot-cta{flex-wrap:nowrap}
  .foot-cta-btn{align-self:center}
}
@media(max-width:660px){
  .foot-cta-btn{width:100%;align-self:stretch;justify-content:center}
}

/* ── Docs tables ─────────────────────────────────────────────
   .docs-table had no styling at all: the reset stripped cell padding and
   borders, so Statuses and PHP SDK methods rendered as one dense block of text
   with nothing separating the rows. */
.docs-table{width:100%;border-collapse:collapse;font-size:14.5px;
  border:1px solid var(--line);border-radius:12px;overflow:hidden}
.docs-table thead th{text-align:left;padding:11px 14px;background:var(--blue-tint);
  font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
  color:var(--slate);border-bottom:1px solid var(--line);white-space:nowrap}
.docs-table td{padding:12px 14px;border-bottom:1px solid var(--line-soft);
  line-height:1.55;color:var(--ink-soft);vertical-align:top}
.docs-table tbody tr:last-child td{border-bottom:0}
.docs-table tbody tr:nth-child(even){background:#fbfcff}
/* Vertical rules as well as horizontal, so a wide row cannot be misread across
   columns on a narrow screen. */
.docs-table td+td,.docs-table th+th{border-left:1px solid var(--line-soft)}
.docs-table code{font-family:var(--mono);font-size:12.5px;background:var(--blue-wash);
  color:var(--blue-deep);padding:3px 7px;border-radius:6px;white-space:nowrap}
/* First column holds the status or method name, so it should not wrap mid-token. */
.docs-table td:first-child{white-space:nowrap}
/* The run/do-not-run column, previously unstyled so all three read the same. */
.docs-table td.yes{color:#0a7a56;font-weight:650}
.docs-table td.no{color:#b42318;font-weight:650}
.docs-table td.warn{color:#8a5a04;font-weight:650}

/* Horizontal scroll is the fallback on narrow screens, with a visible edge so it
   is obvious there is more to the right. */
.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;
  border-radius:12px;margin-bottom:18px}
.table-scroll .docs-table{min-width:520px}

@media(max-width:640px){
  .docs-table{font-size:13.5px}
  .docs-table thead th{padding:9px 11px}
  .docs-table td{padding:10px 11px}
  .docs-table code{font-size:11.5px;padding:2px 6px}
  .table-scroll .docs-table{min-width:470px}
}

/* The floating tiles hold generated 3D marks now, not inline line icons, so they
   need a size rather than inheriting currentColor. */
.fb img{width:34px;height:34px;display:block;
  filter:drop-shadow(0 4px 8px rgba(10,22,80,.22))}
.fb-coin img{width:52px;height:52px}


/* ── Orbit ring around the mascot ────────────────────────────
   The ring itself rotates; the marks are pinned to its edge so they are carried
   round it. Each mark counter-rotates at the same duration, so it travels the
   circle while staying the right way up rather than tumbling.

   Behind the mascot (z-index below it) so a mark passes behind the character on
   the far side of the circle, which is what makes it read as a real orbit. */
.orbit-ring{position:absolute;inset:4% 4% 8% 4%;border-radius:50%;
  border:1px dashed rgba(31,82,255,.16);
  animation:orbitspin 26s linear infinite;z-index:1;pointer-events:none}
.or-mark,.or-dot{position:absolute;animation:orbitspin 26s linear infinite reverse}
.or-mark{width:44px;height:44px;border-radius:14px;display:flex;align-items:center;
  justify-content:center;
  background:linear-gradient(145deg,rgba(255,255,255,.96),rgba(233,240,255,.74));
  border:1px solid rgba(255,255,255,.85);
  box-shadow:0 14px 26px -10px rgba(10,22,80,.28),inset 0 1.5px 0 rgba(255,255,255,1)}
.or-mark img{width:26px;height:26px;display:block}
.or-dot{width:9px;height:9px;border-radius:50%;background:var(--blue);opacity:.5}

/* Pinned to the circle's edge: top centre, right centre, and two points between.
   The negative margins centre each one on the path rather than beside it. */
.or-1{top:-22px;left:50%;margin-left:-22px}
.or-2{bottom:-22px;left:50%;margin-left:-22px}
.or-d1{top:50%;left:-4.5px;margin-top:-4.5px}
.or-d2{top:50%;right:-4.5px;margin-top:-4.5px}

@keyframes orbitspin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){
  .orbit-ring,.or-mark,.or-dot{animation:none}
}
/* Hidden with the floating tiles: there is no room to circle anything on a
   narrow screen. */
@media(max-width:900px){.orbit-ring{display:none}}

/* ── Account settings (/account/settings) ────────────────────
   Reuses .set-* from the vendor store settings, plus the pieces specific to a
   buyer's account: the avatar row and the read-only sign-in block. */
.set-avatar-row{display:flex;align-items:center;gap:20px;flex-wrap:wrap}
.set-avatar{width:84px;height:84px;border-radius:24px;flex-shrink:0;overflow:hidden;
  background:var(--blue);color:#fff;display:flex;align-items:center;justify-content:center;
  font-size:30px;font-weight:750;letter-spacing:-.02em;
  box-shadow:0 10px 26px -8px rgba(31,82,255,.45)}
.set-avatar img{width:100%;height:100%;object-fit:cover;display:block}
/* Loading state for any value the dashboard fills in from the API.

   Used instead of shipping a made-up 0 or a dash that gets replaced a moment
   later: a wrong number on screen is worse than an obvious placeholder. Holds
   its space so nothing jumps when the real value lands, and the inline script
   in the dashboard layout clears the class the moment it does. */
.is-pending{position:relative;color:transparent !important;background-image:linear-gradient(90deg,rgba(255,255,255,.07) 25%,rgba(255,255,255,.16) 37%,rgba(255,255,255,.07) 63%);background-size:400% 100%;border-radius:7px;animation:setShimmer 1.3s ease-in-out infinite}
/* Each needs a size to hold, since an emptied element collapses. */
.is-pending{display:inline-block;min-width:56px;min-height:1em;vertical-align:middle}
.set-hero h2.is-pending{min-width:190px;min-height:19px}
.set-hero a.is-pending{min-width:130px;min-height:12px}
.set-avatar.is-pending{display:flex;min-width:0}
.stat-n.is-pending{min-width:96px;min-height:22px}
.hero-count b.is-pending{min-width:34px;min-height:20px}
/* On the light dashboard cards the white shimmer is invisible, so it darkens. */
.set-card .is-pending,.dash-card .is-pending,.stat .is-pending,.set-hero-t .is-pending{background-image:linear-gradient(90deg,rgba(10,17,48,.06) 25%,rgba(10,17,48,.13) 37%,rgba(10,17,48,.06) 63%)}
@keyframes setShimmer{0%{background-position:100% 50%}100%{background-position:0 50%}}
@media (prefers-reduced-motion: reduce){.is-pending{animation:none}}
.set-avatar-copy{flex:1;min-width:200px}
.set-avatar-copy strong{display:block;font-size:15px;color:var(--ink);margin-bottom:4px}
.set-avatar-copy p{font-size:13px;color:var(--slate);margin:0 0 12px;line-height:1.5}
.set-avatar-actions{display:flex;gap:9px;flex-wrap:wrap}
.btn-sm{padding:9px 16px;font-size:13.5px}
.btn-ghost.danger{color:#b42318;border-color:#f3d0cc}
.btn-ghost.danger:hover{background:#fff5f4;border-color:#e8b4ae}

.set-divider{height:1px;background:var(--line-soft);margin:24px 0}
.set-grid-2{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}

/* A field that is deliberately not editable here. */
.set-locked{position:relative}
.set-locked .auth-input{background:var(--blue-tint);color:var(--slate);cursor:default;
  padding-right:42px}
.set-lock{position:absolute;right:14px;top:50%;transform:translateY(-50%);
  color:var(--slate-light);pointer-events:none;display:flex}

.set-note{display:flex;gap:12px;background:var(--blue-tint);border:1px solid var(--line);
  border-radius:13px;padding:15px 17px;margin-top:16px}
.set-note-ic{color:var(--blue);flex-shrink:0;display:flex;margin-top:1px}
.set-note-ic.google{color:#0a7a56}
.set-note p{font-size:13.5px;line-height:1.6;color:var(--ink-soft);margin:0}
.set-note a{color:var(--blue);font-weight:600;text-decoration:none}
.set-note a:hover{text-decoration:underline}

.set-msg{padding:12px 16px;border-radius:12px;font-size:14px;line-height:1.5;margin-bottom:18px}
.set-msg.err{background:#fdeaea;border:1px solid #f6c9c9;color:#b3261e}
.set-msg.ok{background:var(--green-wash);border:1px solid #b8ead6;color:#0a7a56}

@media(max-width:640px){
  /* Was gap:0. The gap on .auth-field is between a label and its input, not
     between fields, so once these stacked the two names sat flush together. */
  .set-grid-2{grid-template-columns:1fr;gap:13px}
  /* justify-content:stretch is not a packing value flex honours, so it did
     nothing; the full-width button below is what was actually doing the work. */
  .set-actions .btn{width:100%;min-width:0}

  /* Everything on settings comes down a size on a phone. These pages are one
     long column of headings, labels and boxes, and at desktop weights that
     column reads as shouting: eight bold section headings and forty bold
     labels stacked with nothing else to balance them. */
  .set-sec{margin-bottom:24px}
  .set-sec-head{margin-bottom:11px}
  .set-sec-head h3{font-size:14px}
  .set-sec-head p{font-size:12px;line-height:1.55}
  .set-card{gap:13px}
  .set-divider{margin:18px 0}
  .auth-field{gap:5px}
  .auth-label{font-size:11px;font-weight:600}
  .auth-input{font-size:13.5px;padding:11px 13px;border-radius:10px}
  .auth-hint,.set-note{font-size:11.5px}
  .set-actions{padding-top:14px;margin-top:2px}
  .set-actions .btn{padding:11px 16px;font-size:13.5px}

  /* The header block at the top of the page. */
  .set-hero{padding:16px;gap:14px}
  .set-hero-t h2{font-size:16px}
  .set-hero-t a{font-size:11.5px}
  .set-split-t{font-size:11.5px}
  .set-avatar{width:60px;height:60px;border-radius:18px;font-size:22px}
  .set-hero-id{gap:12px}
  .set-hero .set-avatar{width:44px;height:44px;border-radius:13px;font-size:17px}
  .set-avatar-row{gap:14px}
  .set-avatar-copy strong{font-size:13.5px}
  .set-avatar-copy p{font-size:12px;margin-bottom:10px}
}

/* Real profile pictures on comments and reviews, falling back to the initials
   that were there before when somebody has not set one. */
.cm-av img,.rv-av img{width:100%;height:100%;object-fit:cover;display:block;border-radius:inherit}
.cm-av,.rv-av{overflow:hidden}

/* ── Requests: buyer threads with a seller, and with us ──────
   One set of styles for both sides. The buyer sees them at
   /account/tickets, the seller at /dashboard/support. */
.tk-list{display:flex;flex-direction:column;gap:9px}
.tk-row{display:flex;align-items:center;gap:14px;width:100%;text-align:left;cursor:pointer;
  background:#fff;border:1px solid var(--line);border-radius:12px;padding:13px 15px;
  font:inherit;color:inherit;transition:border-color .15s}
.tk-row:hover{border-color:#cfd5e6}
.tk-row-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.tk-row-subject{font-size:14px;font-weight:700;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tk-row-sub{font-size:12px;color:var(--slate)}
.tk-status{flex-shrink:0;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;
  padding:3px 9px;border-radius:20px;background:var(--blue-wash);color:var(--blue)}
.tk-status.s-answered{background:var(--green-wash);color:#0a7a56}
.tk-status.s-closed{background:#eef0f4;color:var(--slate)}

.tk-thread{background:#fff;border:1px solid var(--line);border-radius:14px;padding:18px}
/* Used on /account/tickets, which is a white page. There the card was a white
   box on a white ground wrapping message bubbles that are themselves boxes, so
   only its outline was doing anything, and what it outlined needed no outline.
   The seller dashboard keeps the card: that page is tinted, so it separates. */
.tk-thread-flat{background:none;border:0;border-radius:0;padding:0}
.tk-back{display:inline-flex;align-items:center;gap:6px;background:none;border:0;padding:0;
  font-size:12.5px;font-weight:700;color:var(--blue);cursor:pointer;margin-bottom:14px}
.tk-back:hover{text-decoration:underline}
.tk-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;flex-wrap:wrap;
  padding-bottom:14px;border-bottom:1px solid var(--line-soft)}
.tk-head h2{font-size:16px;font-weight:800;margin:0 0 3px}
.tk-meta{font-size:12px;color:var(--slate);margin:0}

/* The buyer's purchase, shown to the seller so they need not ask for it. */
.vs-lic{display:flex;flex-wrap:wrap;gap:8px 20px;padding:11px 13px;margin-top:14px;
  background:var(--blue-tint);border-radius:10px;font-size:12.5px;color:var(--ink-soft)}
.vs-lic b{color:var(--slate);font-weight:600;margin-right:4px}
.vs-lic code{font-family:var(--mono);font-size:12px;color:var(--ink)}

.tk-msgs{display:flex;flex-direction:column;gap:12px;margin:16px 0}
.tk-msg{border:1px solid var(--line);border-radius:11px;padding:12px 14px;background:#fff}
/* The other side's messages are tinted, so a thread reads as a conversation
   rather than a column of identical blocks. */
.tk-msg.r-vendor,.tk-msg.r-admin{background:var(--blue-tint);border-color:#dbe3fb}
.tk-msg-head{display:flex;align-items:baseline;gap:9px;margin-bottom:5px}
.tk-msg-head b{font-size:12.5px;font-weight:700;color:var(--ink)}
.tk-msg-head span{font-size:11.5px;color:var(--slate-light)}
.tk-msg p{font-size:13.5px;line-height:1.6;color:var(--ink-soft);margin:0;
  white-space:pre-wrap;word-break:break-word}

.tk-reply textarea{resize:vertical;min-height:96px}
.tk-reply-actions{display:flex;gap:9px;flex-wrap:wrap;margin-top:11px}
.tk-closed{font-size:13px;color:var(--slate);text-align:center;padding:14px 0;margin:0}

#ask-modal .auth-input + .auth-input{margin-top:11px}
#ask-modal textarea{resize:vertical}

@media(max-width:600px){
  .tk-row{padding:11px 12px;gap:10px}
  .tk-thread{padding:14px}
  .tk-reply-actions .btn{flex:1;justify-content:center}
}

/* "Report this item", at the foot of the product sidebar. Deliberately quiet:
   it has to be findable without competing with the buy button. */
.pd-report{display:inline-flex;align-items:center;gap:6px;margin-top:16px;
  font-size:12px;font-weight:600;color:var(--slate-light);text-decoration:none}
.pd-report:hover{color:#b42318}
.pd-report svg{flex-shrink:0}

/* ── Two-factor ──────────────────────────────────────────── */
.tfa-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px}
.tfa-head strong{display:block;font-size:14.5px;color:var(--ink);margin-bottom:3px}
.tfa-head .dash-note{margin:0}
.tfa-badge{flex-shrink:0;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;
  padding:3px 10px;border-radius:20px;background:var(--green-wash);color:#0a7a56}
.tfa-blurb{font-size:13px;color:var(--slate);line-height:1.6;margin:10px 0 0;max-width:52ch}
.tfa-actions{border-top:0;padding-top:0;margin-top:14px;justify-content:flex-start}

.tfa-setup{margin-top:16px;padding:16px;border:1px solid var(--line);border-radius:12px;
  background:var(--blue-tint)}
.tfa-steps{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:18px}
.tfa-steps li{font-size:13.5px;color:var(--ink-soft);line-height:1.6}
.tfa-steps span{display:block;margin-bottom:10px}
/* On white, inside the tinted panel: a QR on a tinted ground can fail to scan. */
.tfa-qr{width:168px;height:168px;display:block;background:#fff;padding:8px;
  border:1px solid var(--line);border-radius:10px}
.tfa-manual{margin-top:10px}
.tfa-manual summary{font-size:12.5px;font-weight:600;color:var(--blue);cursor:pointer}
.tfa-manual p{font-size:12.5px;color:var(--slate);margin:8px 0 6px}
.tfa-manual code{display:block;font-family:var(--mono);font-size:12.5px;word-break:break-all;
  background:#fff;border:1px solid var(--line);border-radius:8px;padding:9px 11px;color:var(--ink)}
/* Wide, spaced digits: a 6-digit code is read back off a phone one glyph at a
   time, and normal tracking makes that harder than it needs to be. */
.auth-otp{max-width:190px;font-family:var(--mono);font-size:20px;font-weight:700;
  letter-spacing:.32em;text-align:center}
.tfa-setup .set-actions{border-top:0;padding-top:0;margin-top:16px;justify-content:flex-start}

@media(max-width:600px){
  .tfa-setup{padding:13px}
  .tfa-qr{width:150px;height:150px}
  .tfa-actions .btn,.tfa-setup .set-actions .btn{width:auto}
}

/* ── /items, unfiltered ──────────────────────────────────────
   A place to start rather than a wall of everything. The filtered results grid
   is pages/browse and keeps its own styles. */
.items-page{padding:26px 0 60px}
.items-head{display:flex;align-items:flex-end;justify-content:space-between;gap:22px;flex-wrap:wrap;margin-bottom:26px}
.items-head h1{font-size:30px;font-weight:800;letter-spacing:-.02em;margin:2px 0 6px}

.items-search{position:relative;display:flex;align-items:center;flex:0 1 340px;min-width:220px}
.items-search input{width:100%;height:42px;padding:0 44px 0 15px;font-size:14px;
  background:#fff;border:1px solid var(--line);border-radius:11px;color:var(--ink);outline:none}
.items-search input:focus{border-color:var(--blue)}
.items-search button{position:absolute;right:5px;width:32px;height:32px;border:0;border-radius:8px;
  background:var(--blue);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center}
.items-search button:hover{background:var(--blue-deep)}

/* ── Category panel ── */
.cat-panel{background:#fff;border:1px solid var(--line);border-radius:16px;padding:20px 22px;margin-bottom:34px}
.cat-panel-h{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:800;
  text-transform:uppercase;letter-spacing:.06em;color:var(--slate);margin:0 0 18px}
/* Four across, and no box around any of them. Each category is its own name,
   its count, and a hairline under it: the rule gives the grid its rhythm, which
   is what a tinted tile was doing badly and heavily. */
.cat-panel-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0 28px}
.cat-col{display:flex;align-items:center;padding:11px 0;text-decoration:none;
  border-bottom:1px solid var(--line-soft)}
.cat-col-h{display:flex;align-items:center;gap:9px;width:100%;min-width:0;
  font-size:14px;font-weight:700;color:var(--ink);transition:color .13s}
.cat-col:hover .cat-col-h{color:var(--blue)}
.cat-col-h svg{flex-shrink:0;color:var(--slate-light);transition:color .13s}
.cat-col:hover .cat-col-h svg{color:var(--blue)}
/* The count is the number of live items, so an empty category is honest about
   being empty rather than looking like a broken link. */
.cat-col-n{margin-left:auto;flex-shrink:0;font-size:11px;font-weight:600;color:var(--slate-light);
  background:var(--blue-tint);border-radius:20px;padding:1px 8px}

.items-sec{margin-bottom:40px}

/* ── Two ways in ── */
.items-tiles{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:40px}
.items-tile{display:flex;align-items:center;gap:14px;padding:18px 20px;border-radius:14px;
  background:#fff;border:1px solid var(--line);transition:border-color .15s,transform .15s}
.items-tile:hover{border-color:#cfd5e6;transform:translateY(-1px)}
.items-tile.dark{background:var(--ink);border-color:var(--ink)}
.items-tile.dark strong,.items-tile.dark .items-tile-go{color:#fff}
.items-tile.dark em{color:rgba(255,255,255,.55)}
.items-tile-ic{flex-shrink:0;width:38px;height:38px;border-radius:11px;display:flex;
  align-items:center;justify-content:center;font-size:17px;background:var(--blue-tint)}
.items-tile.dark .items-tile-ic{background:rgba(255,255,255,.1)}
.items-tile strong{display:block;font-size:14.5px;font-weight:700;color:var(--ink)}
.items-tile em{display:block;font-style:normal;font-size:12.5px;color:var(--slate);margin-top:2px}
.items-tile-go{margin-left:auto;font-size:17px;color:var(--slate-light)}

/* ── Bestsellers beside the seller pitch ── */
.items-split{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:18px;align-items:start}
.sell-panel{position:relative;overflow:hidden;isolation:isolate;background:var(--ink);color:#fff;border-radius:16px;padding:24px}
.sell-panel > *:not(.sell-bg){position:relative;z-index:1}
.sell-panel-tag{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.12em;
  color:rgba(255,255,255,.4);margin-bottom:12px}
.sell-panel h3{font-size:19px;font-weight:800;letter-spacing:-.02em;line-height:1.25;margin:0 0 10px}
.sell-panel p{font-size:13px;line-height:1.65;color:rgba(255,255,255,.6);margin:0 0 16px}
.sell-panel ul{list-style:none;padding:0;margin:0 0 20px;display:flex;flex-direction:column;gap:9px}
.sell-panel li{position:relative;padding-left:22px;font-size:12.5px;color:rgba(255,255,255,.8);line-height:1.5}
.sell-panel li::before{content:"";position:absolute;left:2px;top:.45em;width:7px;height:7px;
  border-radius:50%;background:var(--green)}
.sell-panel .btn-primary{width:100%;justify-content:center}
.sell-panel-link{display:block;text-align:center;margin-top:11px;font-size:12.5px;
  color:rgba(255,255,255,.5)}
.sell-panel-link:hover{color:#fff}

/* ── Popular searches ── */
.pop-chips{display:flex;flex-wrap:wrap;gap:8px}
.pop-chips a{font-size:12.5px;font-weight:600;color:var(--ink-soft);background:#fff;
  border:1px solid var(--line);border-radius:20px;padding:7px 15px;transition:border-color .15s}
.pop-chips a:hover{border-color:var(--blue);color:var(--blue)}

@media(max-width:900px){
  .items-split{grid-template-columns:1fr}
  /* The pitch goes under the items on a narrow screen rather than squeezing a
     300px column next to a grid that no longer has room for one. */
  .sell-panel{order:2}
}
@media(max-width:700px){
  .items-head h1{font-size:24px}
  .items-search{flex:1 1 100%}
  .items-tiles{grid-template-columns:1fr}
  .cat-panel{padding:16px}
  /* No gap override. 16px by 20px was set when a category was a column five
     children deep and needed room to read as a column; a one-line tile does
     not, and the wider gap was the only thing making these look bigger on a
     phone than they do anywhere else. They keep the grid's own 10px. */
}

/* The 3D tile icons replace the emoji that used to sit here. */
img.items-tile-ic{width:44px;height:44px;background:none;border-radius:0}

/* ── The scene behind the seller pitch ───────────────────────
   An editor writing code, and the finished item lifting off it. Atmosphere,
   not content: aria-hidden in the markup and untouchable here, so it can never
   sit between a finger and the Start selling button. */
.sell-bg{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.sell-scene{position:absolute;right:-26px;bottom:-18px;width:216px;height:auto;opacity:.17}

/* Each line draws itself in turn, then the whole set clears and starts over.
   dasharray is set to a length longer than any line here, so one keyframe set
   works for all five without measuring each path. */
.sl{stroke-dasharray:70;stroke-dashoffset:70;animation:slType 7s linear infinite}
.sl2{animation-delay:.5s}
.sl3{animation-delay:1s}
.sl4{animation-delay:1.5s}
.sl5{animation-delay:2s}
@keyframes slType{
  0%{stroke-dashoffset:70}
  10%,58%{stroke-dashoffset:0}
  68%,100%{stroke-dashoffset:70}
}

/* The caret keeps its own rhythm, so it never lines up with the typing. */
.scur{animation:slCaret 1.05s steps(1) infinite}
@keyframes slCaret{0%,50%{opacity:1}51%,100%{opacity:0}}

/* The finished item drifts, which is the only thing in here that moves as a
   whole and the reason the eye reads it as the outcome. */
.sbox{animation:slLift 6.5s ease-in-out infinite;transform-origin:50% 50%}
@keyframes slLift{
  0%,100%{transform:translate3d(0,0,0)}
  50%{transform:translate3d(-4px,-9px,0)}
}

/* Traffic-light dots, breathing gently so the window feels live. */
.sd{animation:slDot 4s ease-in-out infinite}
.sd:nth-of-type(2){animation-delay:.4s}
.sd:nth-of-type(3){animation-delay:.8s}
@keyframes slDot{0%,100%{opacity:.5}50%{opacity:1}}

/* Movement is the effect, so under reduced motion it stops rather than being
   removed: the scene still gives the panel depth, and the code lines have to
   be drawn in rather than left invisible. */
@media(prefers-reduced-motion:reduce){
  .sl,.scur,.sbox,.sd{animation:none !important}
  .sl{stroke-dashoffset:0}
}

@media(max-width:900px){
  /* Under the items the panel is wide and short, so the scene moves to the
     corner rather than sitting behind the button. */
  .sell-scene{width:170px;right:-20px;bottom:-14px;opacity:.13}
}

/* ── Results: filter rail + grid ─────────────────────────────
   Every control in the rail is a link, so each filtered view has its own
   address and the back button behaves. Only price is a form, because two
   numbers cannot be a link. */
.browse-layout{display:grid;grid-template-columns:236px minmax(0,1fr);gap:24px;align-items:start;margin-top:20px}
/* Both columns must be allowed to shrink. A grid item defaults to
   min-width:auto, which means "never narrower than my content", and content
   here includes a six-pill sort strip. */
.rail{min-width:0}
.results{min-width:0}

.clear-all{display:inline-flex;align-items:center;gap:6px;margin-top:8px;padding:4px 11px;
  font-size:12px;font-weight:600;color:var(--slate);background:#fff;
  border:1px solid var(--line);border-radius:20px}
.clear-all:hover{color:#b42318;border-color:#f3d0cc}

/* The rail is a disclosure on a phone and always open above it. */
.rail-toggle{display:none;align-items:center;gap:8px;width:100%;padding:11px 14px;
  font:600 13.5px var(--sans);color:var(--ink);background:#fff;
  border:1px solid var(--line);border-radius:11px;cursor:pointer}
.rail-n{margin-left:auto;font-size:11px;font-weight:700;color:#fff;background:var(--blue);
  border-radius:20px;padding:1px 8px}
.rail-body{display:flex;flex-direction:column;gap:20px}

.rail-sec h3{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;
  color:var(--slate-light);margin:0 0 9px}
.rail-row{display:flex;align-items:center;gap:8px;padding:6px 9px;margin:0 -9px;border-radius:8px;
  font-size:13px;color:var(--ink-soft)}
.rail-row:hover{background:var(--blue-tint);color:var(--blue)}
.rail-row.on{background:var(--blue-wash);color:var(--blue);font-weight:700}
.rail-c{margin-left:auto;font-size:11px;color:var(--slate-light);font-family:var(--mono)}
.rail-row.on .rail-c{color:var(--blue)}
/* A square that fills when the option is on: a link that behaves like a
   checkbox should look like one. */
.rail-box{width:14px;height:14px;flex-shrink:0;border:1.5px solid var(--line);border-radius:4px;
  background:#fff;position:relative}
.rail-row.on .rail-box{background:var(--blue);border-color:var(--blue)}
.rail-row.on .rail-box::after{content:"";position:absolute;left:4px;top:1px;width:4px;height:8px;
  border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
.rail-stars{color:var(--amber);font-size:12.5px;letter-spacing:1px}
.rail-up{font-size:11.5px;color:var(--slate-light)}

.rail-price{display:flex;align-items:center;gap:6px}
.rail-price input{width:100%;min-width:0;height:34px;padding:0 9px;font-size:12.5px;
  background:#fff;border:1px solid var(--line);border-radius:8px;color:var(--ink);outline:none}
.rail-price input:focus{border-color:var(--blue)}
.rail-price span{color:var(--slate-light);font-size:12px}
.rail-price button{flex-shrink:0;width:34px;height:34px;border:0;border-radius:8px;
  background:var(--blue);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center}
.rail-price button:hover{background:var(--blue-deep)}

.rail-sell{background:var(--ink);color:#fff;border-radius:14px;padding:18px;text-align:center}
.rail-sell img{margin:0 auto 10px}
.rail-sell strong{display:block;font-size:14px;margin-bottom:6px}
.rail-sell p{font-size:12px;line-height:1.6;color:rgba(255,255,255,.6);margin:0 0 14px}
.rail-sell .btn{width:100%;justify-content:center}

/* ── Results bar ── */
.results-bar{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  margin-bottom:16px}
.results-count{font-size:13.5px;color:var(--slate);margin:0}
.results-count strong{color:var(--ink);font-weight:700}
.results-tools{display:flex;align-items:center;gap:10px;margin-left:auto;min-width:0;max-width:100%}
/* Scrolls rather than wrapping: six sorts on one line would push the view
   toggle onto a second row at most laptop widths. */
.sort-pills{display:flex;gap:4px;overflow-x:auto;scrollbar-width:none;min-width:0;flex:1 1 auto;-webkit-overflow-scrolling:touch}
.sort-pills::-webkit-scrollbar{display:none}
.sort-pill{flex-shrink:0;padding:6px 12px;border-radius:20px;font-size:12.5px;font-weight:600;
  color:var(--slate);background:#fff;border:1px solid var(--line);white-space:nowrap}
.sort-pill:hover{color:var(--ink);border-color:#cfd5e6}
.sort-pill.on{background:var(--ink);border-color:var(--ink);color:#fff}
.view-toggle{display:flex;flex-shrink:0;background:#fff;border:1px solid var(--line);border-radius:9px;padding:2px}
.view-toggle a{display:flex;align-items:center;justify-content:center;width:30px;height:28px;
  border-radius:7px;color:var(--slate-light)}
.view-toggle a.on{background:var(--blue-tint);color:var(--blue)}

/* ── List view ──
   The same card, laid on its side: image left, detail right. Reusing the card
   means nothing about it has to be maintained twice. */
.browse-grid.as-list{grid-template-columns:1fr;gap:11px}
.browse-grid.as-list .card{display:grid;grid-template-columns:190px minmax(0,1fr);align-items:stretch}
.browse-grid.as-list .thumb{height:100%;min-height:132px;border-radius:12px 0 0 12px}
.browse-grid.as-list .card-body{display:flex;flex-direction:column;justify-content:center}

.pagination .page.gap{pointer-events:none;color:var(--slate-light);background:none;border-color:transparent}

@media(max-width:1000px){
  .browse-layout{grid-template-columns:1fr}
  .rail-toggle{display:flex}
  /* Collapsed by default on a narrow screen: five filter groups above the
     results would push every item below the fold. */
  .rail-body{display:none;margin-top:12px}
  .rail.open .rail-body{display:flex}
  .rail-sell{display:none}
}
@media(max-width:620px){
  .browse-grid.as-list .card{grid-template-columns:1fr}
  .browse-grid.as-list .thumb{border-radius:12px 12px 0 0;min-height:0}
  .results-tools{width:100%;margin-left:0}
  .sort-pills{flex:1}
}

/* ── Category panel: See more / See less ─────────────────────
   Driven by a checkbox and a sibling selector, so the toggle needs no script
   and no state. The input is off-screen rather than display:none, which would
   take it out of the tab order and make this keyboard-unreachable.

   Which columns are hidden is decided by POSITION, not by a class set on the
   server: the grid has a different number of columns at each width, so "the
   ones past the first two rows" is a different set on each. */
.cat-more-cb{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}

/* Desktop: every category fits in two compact rows now that a tile is a single
   name rather than a column of five children, so nothing is hidden and the
   toggle has nothing to do. It comes back below, where the grid narrows. */
.cat-more-wrap{display:none}

.cat-more-wrap{display:flex;justify-content:center;margin-top:18px}
.cat-more-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 18px;
  border:1px solid var(--line);border-radius:20px;background:#fff;cursor:pointer;
  font-size:12.5px;font-weight:700;color:var(--blue);user-select:none;transition:border-color .15s}
.cat-more-btn:hover{border-color:var(--blue);background:var(--blue-tint)}
.cat-more-btn svg{transition:transform .2s ease}
/* Both labels are in the markup and CSS shows the right one, so nothing has to
   swap text at runtime. */
.cat-more-btn .cm-less{display:none}
.cat-more-cb:checked ~ .cat-more-wrap .cm-more{display:none}
.cat-more-cb:checked ~ .cat-more-wrap .cm-less{display:inline}
.cat-more-cb:checked ~ .cat-more-wrap svg{transform:rotate(180deg)}
/* The label is the visible control, so the input's focus ring belongs on it. */
.cat-more-cb:focus-visible ~ .cat-more-wrap .cat-more-btn{outline:2px solid var(--blue);outline-offset:2px}
@media(prefers-reduced-motion:reduce){.cat-more-btn svg{transition:none}}

/* Tablet: 3 across, two rows shown, so six before the toggle. */
@media(max-width:1024px) and (min-width:641px){
  .cat-panel-grid{grid-template-columns:repeat(3,1fr)}
  .cat-more-wrap{display:flex}
  .cat-panel-grid > .cat-col:nth-child(n+7){display:none}
  .cat-more-cb:checked ~ .cat-panel-grid > .cat-col{display:flex}
}
/* Phone: two per row, one left one right. */
@media(max-width:640px){
  .cat-panel-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:0 16px}
  .cat-col{padding:10px 0}
  .cat-col-h{font-size:13.5px;gap:8px}
  .cat-more-wrap{display:flex;margin-top:14px}
  .cat-panel-grid > .cat-col:nth-child(n+5){display:none}
  .cat-more-cb:checked ~ .cat-panel-grid > .cat-col{display:flex}
}

/* ── Results grid, inside the rail layout ────────────────────
   The global .grid breakpoints count columns against the VIEWPORT, but here the
   grid lives in a column roughly 236px narrower than the page. Above 1000px
   that made four cards where three fit comfortably. */
.results .browse-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
@media(max-width:1100px){.results .browse-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:560px){.results .browse-grid{grid-template-columns:1fr}}
/* List view is one per row at every width, so it must win over the above. */
.results .browse-grid.as-list{grid-template-columns:1fr}

@media(max-width:1000px){
  /* The rail is a disclosure here, so it needs room from the results under it. */
  .browse-layout{gap:14px}
}
@media(max-width:620px){
  .browse-head h1{font-size:24px}
  .results-bar{gap:10px}
  /* Count on its own line, controls under it: side by side leaves the sort
     strip about 120px, which shows one and a half pills. */
  .results-count{width:100%}
  .results-tools{width:100%;margin-left:0}
  /* Full-width taps, and the pills scroll rather than shrink. */
  .sort-pills{flex:1;min-width:0}
  .view-toggle{flex-shrink:0}
  /* A long page list wraps to three rows on a phone otherwise. */
  .pagination{gap:6px}
  /* height is fixed on .page, so padding alone would not shrink it. */
  .pagination .page{min-width:34px;height:34px;padding:0 8px;font-size:12.5px}
}

/* Titles are vendor-supplied, so a single unbroken word is possible. The line
   clamp hides the overflow but only a break rule stops the word setting the
   column's minimum width in the first place. */
.card-body h3{overflow-wrap:anywhere}
/* The empty state lives directly inside .results, which is not a grid, so its
   grid-column is inert there. Stated explicitly so it cannot inherit a width
   from anywhere and reintroduce the sideways scroll. */
.results .empty{grid-column:auto;max-width:100%}


/* ═══════════════════════════════════════════════════════════
   SELLER BADGES
   ═══════════════════════════════════════════════════════════ */
/* A scalloped rosette, not a coloured pill. A row of these reads at a glance as
   a set of things earned, which is what it is; a row of pills reads as tags,
   which is what it is not. The shape is one path reused as both the visible
   medal and, for a country, the clip the flag is poured into, so a flag badge is
   the same object as every other badge beside it. */
.bdg-row{display:flex;flex-wrap:wrap;align-items:center;gap:7px}
.bdg{position:relative;display:inline-flex;line-height:0;cursor:default;outline:none}
.bdg-row{gap:9px}
.bdg-face{position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:46px;height:46px;transition:transform .16s}
.bdg:hover .bdg-face,.bdg:focus-visible .bdg-face{transform:translateY(-3px) scale(1.07)}
/* Two shadows: a tight contact shadow that sits the badge on the surface, and a
   wider soft one for the drop. One shadow alone reads as a sticker. */
.bdg-shape{position:absolute;inset:0;width:100%;height:100%;display:block;
  filter:drop-shadow(0 1px 1px rgba(10,17,48,.28)) drop-shadow(0 5px 10px rgba(10,17,48,.22))}
.bdg:hover .bdg-shape,.bdg:focus-visible .bdg-shape{
  filter:drop-shadow(0 2px 2px rgba(10,17,48,.26)) drop-shadow(0 10px 18px rgba(10,17,48,.26))}
.bdg-bg{fill:var(--bdg-1)}
/* The glyph carries the badge, so it is heavier than the icon weight used
   elsewhere, and lifted off the colour with its own small shadow. */
.bdg-ic{position:relative;display:flex;width:22px;height:22px;color:#fff;
  filter:drop-shadow(0 1px 1.5px rgba(6,12,40,.4))}
.bdg-ic svg{width:100%;height:100%;stroke-width:2.6}
/* The rung, for the badges that have rungs: 500 sales is not the 100 badge. */
/* Sits on the rim, ringed in white so it reads as a separate disc resting on
   the badge rather than a hole punched in it. */
.bdg-tier{position:absolute;right:-2px;bottom:-2px;min-width:18px;height:18px;padding:0 4px;
  border-radius:20px;background:var(--ink);color:#fff;font-size:10.5px;font-weight:800;line-height:18px;
  text-align:center;box-shadow:0 0 0 2px #fff,0 2px 4px rgba(10,17,48,.3);font-variant-numeric:tabular-nums}

/* Tones. Set as one custom property so a new badge needs a single line. */
.bdg-level{--bdg-1:#e8710a}
.bdg-level.t2{--bdg-1:#0aa06e}
.bdg-level.t3{--bdg-1:#1f52ff}
.bdg-level.t4{--bdg-1:#7c3aed}
.bdg-level.t5{--bdg-1:#111827}
.bdg-sales{--bdg-1:#d92d5e}
.bdg-bestseller{--bdg-1:#1f6dff}
.bdg-rated{--bdg-1:#12a3e0}
.bdg-featured{--bdg-1:#f0a415}
.bdg-range{--bdg-1:#0f9d76}
.bdg-veteran{--bdg-1:#6b5bd2}
/* A flag fills the rosette, so there is no fill colour to set; the plate behind
   it only shows through where a flag has transparent edges, which none do. */
.bdg-flag{--bdg-1:#e6e7ec}
.bdg-flag .bdg-ic{color:var(--slate)}

/* Larger, for the profile header where the row is the headline rather than a
   footnote. */
/* The large row, shown in its own panel where there is room to be looked at
   rather than glanced past. */
.bdg-lg{gap:12px}
.bdg-lg .bdg-face{width:60px;height:60px}
.bdg-lg .bdg-ic{width:28px;height:28px}
.bdg-lg .bdg-ic svg{stroke-width:2.4}
.bdg-lg .bdg-tier{min-width:21px;height:21px;line-height:21px;font-size:12px;padding:0 5px}

/* The label. Shown on hover and on keyboard focus, so the meaning of a badge is
   never locked behind a mouse. */
.bdg-tip{position:absolute;bottom:calc(100% + 9px);left:50%;transform:translateX(-50%) translateY(3px);
  min-width:132px;max-width:210px;padding:8px 11px;border-radius:9px;background:var(--ink);color:#fff;
  text-align:center;line-height:1.4;opacity:0;visibility:hidden;pointer-events:none;z-index:20;
  transition:opacity .15s,transform .15s;box-shadow:0 8px 22px rgba(10,17,48,.24)}
.bdg-tip b{display:block;font-size:12px;font-weight:700}
.bdg-tip em{display:block;font-style:normal;font-size:11px;color:#b9bdcc;margin-top:2px}
.bdg-tip::after{content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);
  border:5px solid transparent;border-top-color:var(--ink)}
.bdg:hover .bdg-tip,.bdg:focus-visible .bdg-tip{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0)}
/* First and last in a row sit against the edge of their card, so their label is
   pinned to that edge instead of overflowing past it. */
.bdg-row .bdg:first-child .bdg-tip{left:0;transform:translateX(0) translateY(3px)}
.bdg-row .bdg:first-child:hover .bdg-tip,.bdg-row .bdg:first-child:focus-visible .bdg-tip{transform:translateX(0)}
.bdg-row .bdg:first-child .bdg-tip::after{left:17px}
.bdg-row .bdg:last-child:not(:first-child) .bdg-tip{left:auto;right:0;transform:translateX(0) translateY(3px)}
.bdg-row .bdg:last-child:not(:first-child):hover .bdg-tip,
.bdg-row .bdg:last-child:not(:first-child):focus-visible .bdg-tip{transform:translateX(0)}
.bdg-row .bdg:last-child:not(:first-child) .bdg-tip::after{left:auto;right:12px;transform:none}

@media(hover:none){
  /* No hover on a touch screen, so the label opens on tap instead. */
  .bdg:hover .bdg-tip{opacity:0;visibility:hidden}
  .bdg.is-open .bdg-tip{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0)}
  .bdg-row .bdg:first-child.is-open .bdg-tip,
  .bdg-row .bdg:last-child:not(:first-child).is-open .bdg-tip{transform:translateX(0)}
}

/* ── Store cover, in the seller's settings ──
   Shown at the shape it appears in on the public profile, so what a seller
   picks here is what buyers get rather than a crop they discover afterwards. */
.cov{display:flex;flex-direction:column;gap:12px}
.cov-preview{position:relative;height:132px;border-radius:11px;overflow:hidden;
  background:var(--blue-tint);border:1px solid var(--line)}
.cov-preview img{width:100%;height:100%;object-fit:cover;display:block}
.cov-empty{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:7px;color:var(--slate-light);font-size:12.5px}
.cov-actions{display:flex;align-items:center;flex-wrap:wrap;gap:9px}
.cov-actions .auth-hint{flex:1 1 100%;margin:0}

/* Popular help chips on a phone.
   Four short chips were taking three lines: the "Popular" label ate a third of
   the first one, and at 13.5px with 15px of padding each chip is wider than a
   quarter of a 390px screen. The label moves above, the type and padding come
   down, and the row is set to never wrap, so they stay on one line at every
   phone width. Below about 340px the row scrolls rather than folding, which
   keeps the promise on the narrowest handsets too. */
@media(max-width:640px){
  .hc-popular{display:block;margin-top:18px}
  .hc-popular-l{display:block;margin:0 0 8px;font-size:10px}
  .hc-chips{flex-wrap:nowrap;gap:4px;overflow-x:auto;scrollbar-width:none;
    -webkit-overflow-scrolling:touch;padding-bottom:2px}
  .hc-chips::-webkit-scrollbar{display:none}
  .hc-chip{flex:0 0 auto;white-space:nowrap;padding:5px 8px;font-size:11px;gap:5px;border-radius:20px}
  /* No lift on touch: there is no hover to lift out of, and the transform only
     ever fired as a stuck state after a tap. */
  .hc-chip:hover{transform:none}
}

/* ═══════════════════════════════════════════════════════════
   ASK THE SELLER  (/account/ask/:uuid)
   ═══════════════════════════════════════════════════════════ */
/* Its own page. It was a dialog, then a panel beside the list; the dialog hid
   the item it was about and the panel floated over the layout and drifted
   against the header on the way down. A page has neither problem and is the
   same thing on every screen, which is what was wanted from it all along. */
.ask-page{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:28px;align-items:start}
.ask-col{min-width:0}
.ask-form{display:flex;flex-direction:column;gap:18px}
.ask-textarea{resize:vertical;min-height:190px;line-height:1.65;font-family:var(--sans)}
.ask-actions{display:flex;gap:10px;flex-wrap:wrap;padding-top:4px}
.ask-actions .btn{padding:12px 24px}

/* What the request is about, so the page carries its own context instead of
   asking the buyer to remember which licence they came from. */
.ask-side{position:sticky;top:calc(var(--nav-h) + 16px);display:flex;flex-direction:column;gap:14px}
.ask-item{display:flex;align-items:flex-start;gap:12px;background:#fff;border:1px solid var(--line);
  border-radius:13px;padding:14px}
.ask-item-th{width:64px;height:48px;flex-shrink:0;border-radius:8px;overflow:hidden;
  background:var(--blue-tint);color:var(--blue);display:flex;align-items:center;justify-content:center}
.ask-item-th img{width:100%;height:100%;object-fit:cover;display:block}
.ask-item-t{min-width:0;display:flex;flex-direction:column;gap:3px}
.ask-item-n{font-size:13.5px;font-weight:700;color:var(--ink);text-decoration:none;line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.ask-item-n:hover{color:var(--blue)}
.ask-item-m{font-size:11.5px;color:var(--slate);text-transform:capitalize}
/* Still loading: the card holds its shape so the column does not appear a beat
   after the form beside it. Arriving from My licences it is never seen, because
   that page hands this one its context before the navigation. */
.ask-item.is-loading .ask-item-th{background:var(--line-soft)}
.ask-item.is-loading .ask-item-n,.ask-item.is-loading .ask-item-m{
  border-radius:5px;background:var(--line-soft);color:transparent;min-height:11px}
.ask-item.is-loading .ask-item-n{width:82%;height:12px}
.ask-item.is-loading .ask-item-m{width:54%;height:10px}
.ask-note{font-size:12px;line-height:1.6;color:var(--slate-light);margin:0;padding:0 2px}
.ask-note a{color:var(--blue);font-weight:600}
.ask-note a:hover{text-decoration:underline}
.ask-note.is-live{color:#0a7a56;font-weight:600}
.ask-note.is-over{color:#a26a05;font-weight:600}

@media(max-width:900px){
  /* The context moves above the form: on a narrow screen it is the first thing
     to confirm before writing, not a footnote beside it. */
  .ask-page{grid-template-columns:1fr;gap:18px}
  .ask-side{position:static;order:-1}
  .ask-note{display:none}
  .ask-note.is-live,.ask-note.is-over{display:block}
}
@media(max-width:640px){
  .ask-form{gap:14px}
  .ask-textarea{min-height:150px}
  .ask-actions{flex-direction:column-reverse}
  .ask-actions .btn{width:100%;justify-content:center}
}

/* ── The moving scene behind "OurCodeMarket Verified" ──
   An isometric floor drifting under boxes that rise and settle. Only transform
   and opacity are animated, so the whole thing lives on the compositor and does
   not touch layout or paint while it runs. */
.fx{position:absolute;inset:0;pointer-events:none;overflow:hidden;border-radius:inherit}
.fx-scene{position:absolute;inset:0;width:100%;height:100%;display:block}
/* Behind the copy, in front of the flat gradient. */
.feature>.orb,.feature>.fx{z-index:0}
.feature>div:not(.orb):not(.fx){position:relative;z-index:1}

/* The floor. It travels exactly one tile of the pattern, so the loop has no
   seam: at 100% it is showing what it showed at 0%, one tile along. */
.fx-grid{opacity:.16}
.fx-grid-in{animation:fxpan 14s linear infinite}
@keyframes fxpan{from{transform:translate3d(0,0,0)}to{transform:translate3d(40px,0,0)}}

.fx-box{animation:fxfloat 7s ease-in-out infinite;transform-origin:center}
/* Back to front: the far boxes are smaller, fainter and slower, which is what
   makes the set read as having depth rather than as four shapes on one plane. */
.fx-box.b1{opacity:.85;animation-duration:6.5s}
.fx-box.b2{opacity:.6;animation-duration:8.5s;animation-delay:-2.2s}
.fx-box.b3{opacity:.45;animation-duration:9.5s;animation-delay:-4.5s}
.fx-box.b4{opacity:.32;animation-duration:11s;animation-delay:-1.1s}
@keyframes fxfloat{
  0%,100%{transform:translate3d(0,0,0)}
  50%{transform:translate3d(-5px,-13px,0)}
}

@media(prefers-reduced-motion:reduce){
  .fx-grid-in,.fx-box{animation:none}
}

/* One way to pay is not a choice, so the row stops looking like a chooser. */
.co-tabs.is-only .co-tab{cursor:default;border-bottom-color:transparent;color:var(--slate)}
.co-tabs.is-only .co-tab.is-on{color:var(--ink);border-bottom-color:transparent}

/* Waiting on the balance, in the moment before the cached figure lands. A bar,
   not a sentence: nobody wants to read "checking..." on a page where they are
   about to pay. */
.co-balance.is-waiting{padding:0;background:none;border:0}
.co-balance.is-waiting span{display:block;height:15px;width:230px;max-width:100%;margin:0 auto;
  border-radius:20px;background:linear-gradient(90deg,var(--line-soft),#e9ecf3,var(--line-soft));
  background-size:200% 100%;animation:coskel 1.1s linear infinite}

/* Arrived from a seller's profile: which seller, and a way back to them. */
.sp-about{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:11px 14px;margin-bottom:18px;
  background:var(--blue-tint);border:1px solid var(--line);border-radius:11px;
  font-size:13px;color:var(--slate)}
.sp-about svg{color:var(--blue);flex-shrink:0}
.sp-about b{color:var(--ink);font-weight:700;text-transform:capitalize}
.sp-about a{margin-left:auto;font-size:12.5px;font-weight:600;color:var(--blue);white-space:nowrap}
.sp-about a:hover{text-decoration:underline}


/* ── Contact page ── */
/* The honeypot. Off-screen rather than display:none, because some bots skip
   hidden fields but fill in anything they can read in the markup. Never
   focusable, and hidden from screen readers by aria-hidden on the wrapper. */
.ct-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
/* The spam sum. Centred and small: it is a doorbell, not part of the message,
   so it should not carry the same weight as the fields above it. */
.ct-sum{margin:4px 0 26px;text-align:center}
.ct-sum-row{display:inline-flex;align-items:center;gap:9px;padding:8px 9px 8px 14px;
  border:1px solid var(--line);border-radius:12px;background:var(--blue-tint)}
.ct-sum-q{font-size:15px;font-weight:700;color:var(--ink);white-space:nowrap;cursor:pointer;
  font-variant-numeric:tabular-nums}
.ct-sum-in{width:56px;padding:8px 6px;text-align:center;font-size:15px;font-weight:700;
  font-family:inherit;color:var(--ink);background:#fff;border:1px solid var(--line);
  border-radius:9px;outline:none;font-variant-numeric:tabular-nums}
.ct-sum-in:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(31,82,255,.14)}
.ct-sum-note{margin:9px 0 0;font-size:12px;color:var(--slate-light)}
.ct-detail{display:flex;gap:10px;align-items:flex-start;font-size:13.5px;line-height:1.6;margin:0 0 10px}
.ct-detail-l{flex:0 0 62px;font-size:11px;letter-spacing:.07em;text-transform:uppercase;font-weight:700;
  color:var(--slate-light);padding-top:3px}
.ct-detail a{color:var(--blue);font-weight:600;word-break:break-word}
.ct-detail a:hover{text-decoration:underline}


/* ── Item page: the cover as a control ── */
/* The cover opens the live preview, so it has to look pressable. A button and
   an anchor both land here, so the button's own chrome is reset. */
a.pd-media,button.pd-media{padding:0;font:inherit;color:inherit;text-align:left;cursor:pointer;width:100%}
.pd-media.is-live{transition:border-color .15s,box-shadow .15s}
.pd-media.is-live:hover{border-color:var(--blue);box-shadow:0 10px 30px -12px rgba(31,82,255,.45)}
.pd-media.is-live:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
.pd-media.is-live .pd-media-img{transition:transform .35s ease}
.pd-media.is-live:hover .pd-media-img{transform:scale(1.03)}
/* The cue names what a click does. Sat on the image rather than under it, so it
   cannot be mistaken for a caption. Used by the screenshots-only cover, which
   opens in place and so needs no confirming tap. */
.pd-media-cue{position:absolute;left:12px;bottom:12px;z-index:2;display:inline-flex;align-items:center;gap:7px;
  padding:7px 12px;border-radius:20px;background:rgba(8,12,30,.72);color:#fff;font-size:12.5px;font-weight:650;
  backdrop-filter:blur(6px);opacity:.94;transition:opacity .15s,transform .15s}
.pd-media.is-live:hover .pd-media-cue{opacity:1;transform:translateY(-1px)}

/* ── The cover that reveals a preview button ── */
/* Tap once to bring the button up, tap it to go. The cover is not a link, so
   the pointer says "this does something" without promising navigation. */
.pd-media-tap{cursor:pointer}
/* A wash over the artwork while the button is showing, so the button reads
   against a busy screenshot instead of fighting it. */
.pd-media-tap::after{content:"";position:absolute;inset:0;z-index:1;background:rgba(6,10,26,.42);
  opacity:0;transition:opacity .18s;pointer-events:none}
.pd-media-tap.is-open::after{opacity:1}

.pd-media-play{position:absolute;top:50%;left:50%;z-index:2;
  transform:translate(-50%,-50%) scale(.92);
  display:inline-flex;align-items:center;gap:9px;
  padding:12px 20px;border-radius:30px;background:#fff;color:var(--ink);
  font-size:14px;font-weight:700;text-decoration:none;white-space:nowrap;
  box-shadow:0 12px 30px -8px rgba(6,10,26,.55);
  opacity:0;visibility:hidden;transition:opacity .18s,transform .18s,visibility .18s}
.pd-media-play svg{color:var(--blue)}
.pd-media-tap.is-open .pd-media-play,
.pd-media-play:focus-visible{opacity:1;visibility:visible;transform:translate(-50%,-50%) scale(1)}
.pd-media-play:hover{background:var(--blue);color:#fff}
.pd-media-play:hover svg{color:#fff}
.pd-media-play:focus-visible{outline:3px solid var(--blue);outline-offset:3px}
/* Pointer devices can show it on hover: there is no accidental-tap problem
   with a mouse, and hiding it there would just be a step for no reason. */
@media (hover:hover) and (pointer:fine){
  .pd-media-tap:hover .pd-media-play{opacity:1;visibility:visible;transform:translate(-50%,-50%) scale(1)}
  .pd-media-tap:hover::after{opacity:1}
}

/* ── Item page: tags, folded ── */
/* Everything past the third is in the page but hidden, so a crawler still sees
   the full set while the panel stays short. Revealed by the toggle. */
.pd-tags [data-extra]{display:none}
.pd-tags.is-open [data-extra]{display:inline-block}
.pd-tag-more{font-size:11.5px;font-weight:600;color:var(--slate);background:none;border:1px dashed var(--line);
  padding:3px 9px;border-radius:20px;cursor:pointer;font-family:inherit;white-space:nowrap}
.pd-tag-more:hover{color:var(--blue);border-color:var(--blue)}
/* Wider screens have room for more before it crowds. */
@media (min-width:1100px){
  .pd-tags [data-extra]:nth-of-type(-n+5){display:inline-block}
}

/* The features heading, now that the list follows the description instead of
   opening the panel. */
.pd-feat-h{font-size:15px;font-weight:750;color:var(--ink);margin:26px 0 12px}
