/* iGamingDomains — component library (Design System v6 "Fresh")
   Palette variables are injected per-request by App\Support\Theme::rootCss().
   This file only consumes var(--x), so it is theme-agnostic and buildless.

   Every font-size in this file is one of the 9 admin-configurable tokens
   (--h1/h2/h3/body-size, --fs-2xl/lg/sm/xs/2xs) — see Theme::fontSizes()/
   extraFontSizes() and Settings → Theme. The only exceptions are numeral
   glyphs locked inside a fixed-diameter circle (avatar initials, the
   notification-count dot, wizard-step numbers, the mobile-nav level dot,
   the hamburger ☰ icon) — resizing those independently of their container
   would just overflow or clip the circle, so they stay literal pixels. */

/* DM Sans — self-hosted variable font (covers weights 400-700), same reasoning as the
   bundled JetBrains Mono used for the share-image generator: no CDN dependency. */
@font-face{
  font-family:'DM Sans';
  src:url('/fonts/DMSans-Variable.woff2') format('woff2');
  font-weight:400 700;
  font-style:normal;
  font-display:swap;
}

:root{
  --sans:'DM Sans',-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  --font-heading:'DM Sans',-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  --mono:ui-monospace,"SF Mono","JetBrains Mono",Menlo,monospace;
  /* Rounder, friendlier radius scale (v6) — was 8/12/14/18 */
  --r-sm:10px; --r:14px; --r-lg:20px; --r-xl:28px; --pill:999px;
  --maxw:1180px;
  /* Flat design system (v4) — hairline borders do the separating, shadows are only
     ever a faint lift on hover, never a resting-state glow. */
  --sh-1:0 1px 2px rgba(0,0,0,.5);
  --sh-2:0 4px 10px -4px rgba(0,0,0,.4);
  --sh-3:0 8px 20px -8px rgba(0,0,0,.35);
  /* Bitcoin's own brand orange — fixed, not admin-themeable, same in light/dark
     (matching an external brand color shouldn't shift with the site's own palette). */
  --btc:#F7931A;
}
[data-mode="light"]{
  --sh-1:0 1px 2px rgba(20,20,20,.06);
  --sh-2:0 4px 10px -4px rgba(20,20,20,.08);
  --sh-3:0 8px 20px -8px rgba(20,20,20,.1);
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--bg);
  color:var(--text);font-family:var(--sans);line-height:1.55;min-height:100vh;
  -webkit-font-smoothing:antialiased;font-size:var(--body-size,16px)}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{margin:0;text-wrap:balance;letter-spacing:-.02em;line-height:1.15;font-family:var(--font-heading)}
h1{font-size:var(--h1-size,32px)} h2{font-size:var(--h2-size,24px)} h3{font-size:var(--h3-size,19px)}
p{margin:0}
img{max-width:100%;display:block}
.mono{font-family:var(--mono)} .tnum{font-variant-numeric:tabular-nums}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}
.muted{color:var(--text-2)} .faint{color:var(--text-3)}
.stack{display:flex;flex-direction:column}
.row{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.between{justify-content:space-between}
.center{justify-content:center}
/* min-width:0 prevents "grid blowout" — a 1fr track otherwise refuses to shrink below
   its content's intrinsic (min-content) width, so any wide descendant (e.g. the payment
   logo strip before it's clipped) would inflate the whole column and push the layout
   into horizontal overflow instead of being contained by its own overflow:hidden. */
.grid{display:grid;gap:16px}
.grid>*{min-width:0}
.cols-2{grid-template-columns:repeat(2,1fr)} .cols-3{grid-template-columns:repeat(3,1fr)}
.cols-4{grid-template-columns:repeat(4,1fr)}
/* Sale page: description on the left gets the lion's share, the acquisition card on the
   right stays a narrower, focused ~1/3 column instead of splitting the page 50/50. */
.sale-layout{grid-template-columns:2fr 1fr}
@media(max-width:900px){.cols-2,.cols-3,.cols-4,.sale-layout{grid-template-columns:1fr}}
@media(min-width:600px) and (max-width:900px){.cols-3,.cols-4{grid-template-columns:repeat(2,1fr)}}
.mt-1{margin-top:8px}.mt-2{margin-top:16px}.mt-3{margin-top:24px}.mt-4{margin-top:40px}
.mb-2{margin-bottom:16px}.mb-3{margin-bottom:24px}
.panel{background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r-lg);padding:22px}
.lbl{font-size:var(--fs-2xs,11px);font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--text-3)}

/* ===== brand / nav ===== */
.topbar{position:sticky;top:0;z-index:50;backdrop-filter:blur(14px);
  background:color-mix(in srgb,var(--bg) 78%,transparent);border-bottom:1px solid var(--border)}
.topbar .wrap{display:flex;align-items:center;gap:16px;height:64px;position:relative}
.brand{display:flex;align-items:center;gap:10px;font-weight:700;letter-spacing:-.02em;font-size:17px}
.brandmark{width:32px;height:32px;border-radius:9px;display:grid;place-items:center;
  background:var(--primary);
  color:var(--ptext);font-weight:800;font-size:14px}
.brand .g{color:var(--primary)} .brand .io{color:var(--primary)}
.navlinks{display:flex;gap:4px;margin-left:auto;align-items:center;flex-wrap:wrap}
.navlinks a:not(.btn){font-size:var(--fs-sm,14px);color:var(--text-2);padding:8px 12px;border-radius:9px}
.navlinks a:not(.btn):hover,.navlinks a:not(.btn).active{color:var(--text);background:var(--surface)}

/* User profile menu — a <details> dropdown (open/close is native, no JS needed; the tiny
   layout script only adds close-on-outside-click). Panel styling follows the same
   absolute-positioned pattern as .msel-panel/.csel-panel. */
.nav-user{position:relative}
.nav-user>summary{list-style:none;display:flex;align-items:center;gap:7px;cursor:pointer;
  font-size:var(--fs-sm,14px);color:var(--text-2);padding:6px 10px;border-radius:9px;user-select:none}
.nav-user>summary::-webkit-details-marker{display:none}
.nav-user>summary:hover,.nav-user[open]>summary{color:var(--text);background:var(--surface)}
.nav-user[open]>summary .icon{transform:rotate(180deg)}
.nav-user>summary .icon{transition:transform .15s;color:var(--text-3)}
.nav-user-avatar{display:grid;place-items:center;width:26px;height:26px;border-radius:50%;
  background:var(--primary);color:var(--ptext);font-size:12.5px;font-weight:700;flex:none}
.nav-user-avatar-wrap{position:relative;display:inline-flex;flex:none}
.notif-badge{position:absolute;top:-5px;right:-6px;min-width:15px;height:15px;padding:0 3px;
  display:grid;place-items:center;border-radius:999px;background:var(--danger);color:#fff;
  font-size:10px;line-height:1;font-weight:700;font-variant-numeric:tabular-nums;
  border:1.5px solid var(--bg);pointer-events:none}
.stat .notif-badge,.nav-user-menu .notif-badge{position:static;display:inline-grid;margin-left:6px;vertical-align:middle;
  border:0}
.nav-user-name{font-weight:600;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nav-user-menu{position:absolute;right:0;top:calc(100% + 6px);z-index:60;min-width:180px;
  background:var(--surface);border:1px solid var(--border);border-radius:10px;
  box-shadow:var(--sh-3);padding:6px;display:flex;flex-direction:column}
.nav-user-menu a,.nav-user-menu button{display:block;width:100%;text-align:left;font-size:var(--fs-sm,14px);
  font-family:var(--sans);color:var(--text-2);padding:9px 12px;border-radius:8px;
  background:transparent;border:0;cursor:pointer}
.nav-user-menu a:hover,.nav-user-menu button:hover{background:var(--bg-2);color:var(--text)}
.nav-user-menu form{margin:0;border-top:1px solid var(--border);margin-top:4px;padding-top:4px}

/* Mobile nav — a CSS-only checkbox toggle (no JS needed): the wide desktop nav row
   wraps onto 3+ cramped lines below ~700px, pushing all page content down behind a
   tall header. Collapse it behind a hamburger button that reveals a dropdown instead. */
.nav-toggle-input{display:none}
.nav-toggle-btn{display:none;margin-left:auto;cursor:pointer;font-size:22px;line-height:1;
  padding:6px 4px;color:var(--text)}
@media(max-width:700px){
  .nav-toggle-btn{display:block}
  .navlinks{display:none;position:absolute;top:100%;left:0;right:0;margin-left:0;
    flex-direction:column;align-items:stretch;gap:2px;background:var(--surface);
    border:1px solid var(--border);border-top:0;border-radius:0 0 var(--r-lg) var(--r-lg);
    padding:10px;box-shadow:0 12px 24px rgba(0,0,0,.12)}
  .nav-toggle-input:checked ~ .navlinks{display:flex}
  .navlinks a:not(.btn){padding:12px 14px}
  .navlinks form{margin:2px 0 0}
  .navlinks form .btn{width:100%;justify-content:center}
  /* Inside the hamburger panel the user menu flattens to an inline section — an
     absolute-positioned floating panel makes no sense inside an already-floating menu. */
  .nav-user{width:100%}
  .nav-user>summary{padding:12px 14px}
  .nav-user-menu{position:static;box-shadow:none;border:0;border-top:1px solid var(--border);
    border-radius:0;padding:4px 0 0 14px;min-width:0}
}

/* ===== buttons ===== */
.btn{display:inline-flex;align-items:center;gap:8px;font-family:var(--sans);font-weight:700;
  font-size:var(--fs-sm,14px);line-height:1;border-radius:var(--r);padding:12px 20px;border:1px solid transparent;
  cursor:pointer;transition:.16s ease;white-space:nowrap;text-decoration:none}
.btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--primary-ring)}
/* v6 "fresh": primary action is the real brand lime, used boldly (Hostinger-style single
   accent) — .btn-dark (solid ink) is the secondary strong action, used on card/row "View"
   CTAs where a second lime button next to the price would compete with it. */
.btn-primary{background:var(--btn-primary-bg);color:var(--btn-primary-text)}
.btn-primary:hover{filter:brightness(.92)}
.btn-dark{background:var(--btn-dark-bg);color:var(--btn-dark-text)}
.btn-dark:hover{filter:brightness(1.15)}
.btn-gold{background:var(--gold);color:#20160A}
.btn-gold:hover{filter:brightness(1.05)}
.btn-outline{background:transparent;border-color:var(--border-hi);color:var(--text)}
.btn-outline:hover{border-color:var(--text);background:var(--surface-2)}
.btn-ghost{background:transparent;color:var(--text-2)}
.btn-ghost:hover{background:var(--surface-2);color:var(--text)}
.btn-danger{background:transparent;border-color:var(--danger);color:var(--danger)}
.btn-danger:hover{background:var(--danger-tint)}
/* Neutral, not brand-colored — Google's own button guidelines call for a plain white/dark
   surface with the multi-color "G" mark doing the branding, not a tinted background. */
.btn-google{background:var(--surface);border-color:var(--border-hi);color:var(--text);
  justify-content:center}
.btn-google:hover{background:var(--surface-2);border-color:var(--text-3)}
.btn-block{width:100%;justify-content:center}
.btn-sm{padding:8px 12px;font-size:var(--fs-xs,12px);border-radius:8px}
.btn-lg{padding:14px 22px;font-size:var(--fs-sm,14px);border-radius:12px}
.btn[disabled]{opacity:.45;cursor:not-allowed;filter:none}

/* ===== badges ===== */
.badge{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-xs,12px);font-weight:600;
  padding:5px 11px;border-radius:var(--pill);border:1px solid transparent;line-height:1}
.badge .dot{width:6px;height:6px;border-radius:50%;background:currentColor}
/* Acquisition-type chips (Buy Now / Make Offer / Lease / Rent / Crypto / Site) are all one
   neutral, understated style now — the label text itself carries the meaning, matching a
   reference brand's own restraint (color signals status, not category). */
.b-buy,.b-offer,.b-lease,.b-rent,.b-crypto,.b-site,.b-invest{background:var(--surface-2);color:var(--text-2);border-color:var(--border-hi)}
.b-escrow{background:var(--surface-hi);color:var(--text-2);border-color:var(--border-hi)}
/* Status colors stay semantic — sold/pending are real state signals, not decorative category tags. */
.b-sold{background:var(--danger-tint);color:var(--danger);border-color:color-mix(in srgb,var(--danger) 30%,transparent)}
.b-pending{background:var(--gold-tint);color:var(--gold);border-color:color-mix(in srgb,var(--gold) 32%,transparent)}
/* Acquisition-type badges that are also links (Buy Now/Lease/Rent/Offer, see domain-card
   and domain-row) — text-decoration:none since a pill shouldn't read as underlined prose,
   plus a hover cue since nothing else about a badge otherwise signals it's clickable. */
a.badge{text-decoration:none;transition:filter .12s}
a.badge:hover{filter:brightness(.94)}

/* ===== forms ===== */
.field{display:flex;flex-direction:column;gap:7px;margin-bottom:14px}
/* Same trap as .msel-panel[hidden] further down: the display:flex above is an author
   rule and beats the browser's own [hidden]{display:none}, so a field toggled with the
   hidden attribute (the register form's "Tell us where" box) stayed on screen at full
   height. Applies to every .field, so the next one to be toggled doesn't hit this. */
.field[hidden]{display:none}
.field label{font-size:var(--fs-xs,12px);font-weight:600;color:var(--text-2)}
.input,.select,textarea.input{width:100%;background:var(--bg-2);border:1px solid var(--border-hi);
  color:var(--text);border-radius:10px;padding:11px 13px;font-size:var(--fs-sm,14px);font-family:var(--sans);transition:.15s}
.input::placeholder{color:var(--text-3)}
.input:focus,.select:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-ring)}
.hint{font-size:var(--fs-xs,12px);color:var(--text-3)} .err{font-size:var(--fs-xs,12px);color:var(--danger);margin-top:4px}
.input.is-err{border-color:var(--danger);box-shadow:0 0 0 3px var(--danger-tint)}

/* ===== rich-text editor (Quill, self-hosted — see components/rich-text-editor.blade.php) =====
   Overrides Quill's "snow" theme defaults (white bg, fixed grey borders, system font) to use
   the same tokens as every other form control, in both light and dark mode. */
.rte .ql-toolbar.ql-snow{background:var(--bg-2);border:1px solid var(--border-hi);
  border-bottom:0;border-radius:10px 10px 0 0;padding:8px 10px}
.rte .ql-container.ql-snow{background:var(--bg-2);border:1px solid var(--border-hi);
  border-radius:0 0 10px 10px;font-family:var(--sans);font-size:var(--fs-sm,14px)}
.rte .ql-editor{color:var(--text);min-height:160px;padding:11px 13px}
.rte .ql-editor.ql-blank::before{color:var(--text-3);font-style:normal}
.rte .ql-snow .ql-stroke{stroke:var(--text-2)}
.rte .ql-snow .ql-fill{fill:var(--text-2)}
.rte .ql-snow .ql-picker{color:var(--text-2)}
.rte .ql-snow.ql-toolbar button:hover,.rte .ql-snow .ql-toolbar button:hover,
.rte .ql-snow.ql-toolbar button.ql-active,.rte .ql-snow .ql-toolbar button.ql-active,
.rte .ql-snow .ql-picker-label:hover{color:var(--primary)}
.rte .ql-snow.ql-toolbar button:hover .ql-stroke,.rte .ql-snow .ql-toolbar button:hover .ql-stroke,
.rte .ql-snow.ql-toolbar button.ql-active .ql-stroke,.rte .ql-snow .ql-toolbar button.ql-active .ql-stroke{stroke:var(--primary)}
.rte .ql-snow.ql-toolbar button:hover .ql-fill,.rte .ql-snow .ql-toolbar button:hover .ql-fill,
.rte .ql-snow.ql-toolbar button.ql-active .ql-fill,.rte .ql-snow .ql-toolbar button.ql-active .ql-fill{fill:var(--primary)}
.rte .ql-snow .ql-picker-options{background:var(--surface);border-color:var(--border-hi) !important}
.rte .ql-snow .ql-tooltip{background:var(--surface);border:1px solid var(--border-hi);
  color:var(--text);box-shadow:var(--sh-3);border-radius:10px}
.rte .ql-snow .ql-tooltip input[type=text]{background:var(--bg-2);border:1px solid var(--border-hi);color:var(--text);border-radius:8px}
.rte .ql-snow .ql-tooltip a.ql-action::after{border-color:var(--primary)}
/* WordPress-style Visual/Text tabs — same underline-tab language as .tabnav (settings
   pages), just right-aligned and compact, sitting directly above the toolbar so the two
   modes read as a single control instead of a floating button. */
.rte-tabs{display:flex;justify-content:flex-end;gap:16px;padding:0 2px 7px}
.rte-tab{display:flex;align-items:center;gap:4px;font-size:var(--fs-xs,12px);font-weight:600;
  color:var(--text-3);background:transparent;border:0;padding:0;cursor:pointer;font-family:var(--sans)}
.rte-tab:hover{color:var(--text-2)}
.rte-tab.is-active{color:var(--primary)}
.rte-code{font-family:var(--mono);font-size:var(--fs-sm,14px);border-radius:0 0 10px 10px;resize:vertical}

/* Rendered rich-text output on the public domain page (domains/show.blade.php) — sanitized
   HTML from RichText::sanitize(), so safe to style generically without per-domain CSS. */
/* overflow-wrap:break-word is the safety net for arbitrary seller-submitted content — a
   pasted URL, a long unbroken token, or (see the pre/code override below) a Quill "code
   block" all default to no wrapping otherwise, and silently overflow the panel instead
   of clipping, since nothing here sets overflow:hidden either. Was overflow-wrap:anywhere,
   which is too eager: inside this grid column (see .sale-layout) it let ordinary words
   break mid-letter ("host" as "hos"/"t") even with plenty of room on the line, since
   "anywhere" tells the browser every character is a valid break point, not just a
   last resort. break-word only breaks a word that genuinely can't fit on its own line. */
.rich-text{color:var(--text-2);line-height:1.7;overflow-wrap:break-word}
.rich-text :is(h1,h2,h3,h4){font-family:var(--font-heading);color:var(--text);margin:20px 0 8px;line-height:1.25}
.rich-text :is(h1,h2){font-size:1.3em} .rich-text :is(h3,h4){font-size:1.1em}
.rich-text p{margin:0 0 12px}
.rich-text :is(ul,ol){margin:0 0 12px;padding-left:22px}
.rich-text li{margin-bottom:4px}
.rich-text blockquote{margin:0 0 12px;padding-left:14px;border-left:3px solid var(--border-hi);color:var(--text-3)}
.rich-text a{color:var(--primary);text-decoration:underline}
.rich-text :first-child{margin-top:0} .rich-text :last-child{margin-bottom:0}
/* RichText::sanitize() allows <pre>/<code> through — the browser default of
   white-space:pre means a long unbroken line in one of these just runs off the edge
   of the panel instead of wrapping. Force it to wrap like everything else, and keep
   overflow-x:auto as a last-resort escape hatch for genuinely unbreakable content. */
.rich-text :is(pre,code){white-space:pre-wrap;overflow-wrap:anywhere;overflow-x:auto}
.rich-text pre{background:var(--bg-2);border:1px solid var(--border);border-radius:8px;padding:12px 14px;margin:0 0 12px;font-family:var(--mono);font-size:var(--fs-sm,14px)}

/* ===== search ===== */
.searchbar{display:flex;gap:0;background:var(--surface);border:1px solid var(--border-hi);
  border-radius:12px;padding:6px;position:relative}
.searchbar:focus-within{border-color:var(--text)}
.searchbar .ico{display:grid;place-items:center;width:42px;color:var(--text-3);flex:none}
/* Reads as a real text field rather than a line of placeholder text — the select and the
   button next to it are both obviously interactive, so a bare input was the odd one out. */
.searchbar input{flex:1;background:var(--bg-2);border:1px solid var(--border);border-radius:9px;
  padding:10px 12px;color:var(--text);font-size:var(--fs-sm,14px);outline:none;min-width:60px}
.searchbar input:focus{border-color:var(--primary)}
.searchbar .divider{width:1px;background:var(--border);margin:6px 4px}
.searchbar .tldsel{background:transparent;border:0;border-radius:9px;
  padding:0 12px;font-family:var(--mono);font-size:var(--fs-sm,14px);color:var(--primary);font-weight:600;cursor:pointer}
/* The TLD picker sits inline with the input, not on its own row. flex:none keeps it at its
   natural width so the text box takes the leftover space. */
/* position:static so the dropdown's containing block becomes .searchbar rather than this
   150px control — that's what lets the panel span the full width of the bar below it. */
.searchbar .msel{flex:none;min-width:150px;align-self:center;position:static}
.searchbar .msel-control{border:0;background:transparent;padding:0 10px}
/* Wider and taller than the default panel: this one holds every TLD in the catalogue,
   so 210px cramped the list into a narrow column. max-width keeps it inside the viewport
   on a narrow desktop window, where the panel is anchored to the bar's right edge. */
/* Full width of the search bar, with the TLDs in columns — a single 320px column meant
   scrolling through thirty-odd extensions four at a time. auto-fill sizes the column count
   to whatever width is going, so it degrades to two or three columns on a narrow window
   instead of needing its own breakpoints.
   .msel.msel-js is repeated on the second rule deliberately: the base rule setting
   max-height uses three classes, so a two-class selector silently loses to it. */
.searchbar .msel-panel{left:0;right:0;min-width:0;max-width:none}
.searchbar .msel.msel-js .msel-panel{max-height:340px;display:grid;gap:2px;padding:10px;
  grid-template-columns:repeat(auto-fill,minmax(130px,1fr))}
/* Same trap as .msel-option[hidden] below: the `display:grid` above is an author rule and
   beats the browser's [hidden]{display:none}, so without this the panel would sit open
   permanently instead of only while the control is expanded. Needs the full selector to
   outrank the rule it's correcting. */
.searchbar .msel.msel-js .msel-panel[hidden]{display:none}
/* Neither the filter box nor the clear-all strip is a column — both sit across the top
   of the grid. */
.searchbar .msel-search,.searchbar .msel-actions{grid-column:1/-1}
.searchbar .btn{margin-left:7px}
.tldchips{display:flex;gap:7px;flex-wrap:wrap;margin-top:12px}
.tldchip{font-family:var(--mono);font-size:var(--fs-xs,12px);color:var(--text-2);background:var(--surface);
  border:1px solid var(--border);border-radius:var(--pill);padding:5px 11px;cursor:pointer;text-decoration:none}
.tldchip.on,.tldchip:hover{color:var(--primary);border-color:var(--primary);background:var(--primary-tint)}

/* The homepage search dock. Static on desktop — it reads as part of the hero. On mobile it
   pins under the (also sticky, 64px) top bar so search stays reachable down the whole page. */
.hero-search-dock{margin-top:4px}
.hero-search{max-width:720px;margin-inline:auto}
/* The phone stand-in for the search form: same shape as .searchbar, but one tap target. */
.hero-search-tap{display:none;align-items:center;gap:10px;text-decoration:none;
  background:var(--surface);border:1px solid var(--border-hi);border-radius:12px;padding:14px 16px}
.hero-search-tap .ico{display:grid;place-items:center;color:var(--text-3);flex:none}
.hero-search-tap-label{color:var(--text-3);font-size:var(--fs-sm,14px)}

/* Phone only (matching where the header nav collapses) — a tablet still has room for the
   original single-row bar, so it keeps it. */
@media(max-width:700px){
  .hero-search-dock{position:sticky;top:64px;z-index:40;
    background:var(--bg);padding:10px 0;box-shadow:0 8px 16px -12px rgba(0,0,0,.35)}
  /* Swap the form for the tap target. Everything the form offered — text, TLDs, price,
     payment method, sort — lives in the Browse sheet this opens, so nothing is lost. */
  form.hero-search{display:none}
  .hero-search-tap{display:flex}
  .tldchips{justify-content:center}
}

/* ===== domain card ===== */
.dcard{background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-lg);overflow:hidden;transition:transform .16s,box-shadow .16s,border-color .16s;display:flex;flex-direction:column}
.dcard:hover{border-color:var(--border-hi);transform:translateY(-3px);box-shadow:var(--sh-3)}
/* Featured = an optional black stroke (admin: on/off + width) plus an optional glow-tinted
   background wash (admin: on/off + colour, see --glow), fully independent of each other —
   both default per the approved v6 design (stroke on at 2px, glow off) but the admin can flip either. */
[data-featured-stroke="on"] .dcard.featured{border-color:var(--text);border-width:var(--featured-stroke-width,2px)}
[data-card-glow="on"] .dcard.featured{background:linear-gradient(165deg,color-mix(in srgb,var(--glow) 16%,var(--surface)),var(--surface) 55%)}
.dcard .thumb{min-height:120px;position:relative;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:6px;padding:16px 12px;
  background:var(--bg-2);
  border-bottom:1px solid var(--border)}
.dcard .thumb .dn{font-family:var(--font-heading);font-weight:700;font-size:var(--h3-size,21px);letter-spacing:-.01em;display:inline-flex;align-items:center;gap:6px}
.dcard .thumb .dn .tld{color:var(--primary)}
.dcard .thumb .dn .drow-star{color:var(--primary-700);width:16px;height:16px}
.dcard .thumb .fav{position:absolute;top:10px;right:10px;width:30px;height:30px;border-radius:8px;
  background:color-mix(in srgb,var(--bg) 55%,transparent);border:1px solid var(--border);
  display:grid;place-items:center;color:var(--text-2);cursor:pointer}
.dcard .thumb .feat{position:absolute;top:10px;left:10px}
.dcard .body{padding:15px 16px;display:flex;flex-direction:column;gap:12px;flex:1}
.dcard .meta{display:flex;gap:8px;font-size:var(--fs-xs,12px);color:var(--text-3);flex-wrap:wrap}
.dcard .badges{display:flex;gap:6px;flex-wrap:wrap}
.dcard .foot{margin-top:auto;padding-top:12px;border-top:1px solid var(--border)}
.dcard .foot .btn{width:100%;text-align:center;justify-content:center}
/* Price sits right under the domain name, centered to match the name above it —
   amount and its BTC equivalent always on their own line each (no shared label; the
   card's context already makes it obvious). */
.dcard-price{display:flex;flex-direction:column;align-items:center;gap:2px;text-align:center}
.dcard-price .v{font-size:var(--fs-lg,19px);font-weight:700;font-family:var(--font-heading)}
/* Currency symbol takes the amount's colour, not the brand green — a green "€" beside a
   dark number reads as two things rather than one price. Kept as an explicit rule (not
   just deleted) so the inherit is visibly deliberate. Covers both the grid cards and the
   list rows; the acquisition card's .acq-opt-price b is different — the whole price is
   green there, symbol included, which is consistent on its own terms. */
.dcard-price .v .cur,.drow-price .v .cur{color:inherit}
.dcard-price .btc-amount{justify-content:center}
/* BTC-equivalent line, everywhere it appears (grid cards, list rows, the acquisition
   card) — one shared class so the real Bitcoin logomark + orange brand colour (fixed,
   non-themeable, see --btc above) stay consistent instead of three near-duplicate rules. */
.btc-amount{display:flex;align-items:center;justify-content:flex-end;gap:4px;
  font-size:var(--fs-2xs,11px);color:var(--btc);font-weight:600;margin-top:2px}
.btc-amount .icon{width:11px;height:11px;flex:none}

/* ===== submit wizard: two-column "set terms" form =====
   Descriptions on the left (2/3), a sticky price/payment rail on the right (1/3).
   align-items:start is what lets the short right column actually stick instead of being
   stretched to the tall left column's height. Collapses to a single stacked column — and
   un-sticks — below 900px. */
.submit-layout{grid-template-columns:2fr 1fr;align-items:start}
.submit-side{position:sticky;top:78px}
/* Domain page right rail — align-self:start stops the grid stretching it full-height,
   which would leave sticky no room to move. */
.domain-side{position:sticky;top:78px;align-self:start}
@media(max-width:900px){
  .submit-layout{grid-template-columns:1fr}
  .submit-side{position:static}
  .domain-side{position:static}
}

/* ===== browse: sidebar filters + list ===== */
.browse-layout{display:grid;grid-template-columns:250px 1fr;gap:22px;align-items:start}
.browse-filters{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:18px;position:sticky;top:78px;display:flex;flex-direction:column;gap:16px}
.browse-filters .lbl{font-size:var(--fs-xs,12px)}
.browse-filters .field{margin-bottom:0}
.browse-filters .select,.browse-filters .input{width:100%}
.browse-list{display:flex;flex-direction:column;gap:10px}

/* ===== multi-select chip dropdown (components/multi-select.blade.php) =====
   Base .msel-panel is a plain static checkbox list — the no-JS fallback. Once
   multi-select.js runs it adds .msel-js to the root, which is what switches the
   panel into an absolutely-positioned, toggleable dropdown below a chip control. */
.msel{position:relative}
.msel-panel{border:1px solid var(--border-hi);border-radius:10px;padding:6px;background:var(--bg-2)}
.msel.msel-js{border:0}
.msel.msel-js .msel-panel{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:60;
  background:var(--surface);border-color:var(--border);box-shadow:var(--sh-3);
  max-height:260px;overflow-y:auto}
.msel-control{width:100%;display:flex;align-items:center;justify-content:space-between;gap:8px;
  background:var(--bg-2);border:1px solid var(--border-hi);border-radius:10px;padding:7px 13px;
  min-height:44px;cursor:pointer;font-family:var(--sans);text-align:left}
.msel-control:hover{border-color:var(--text-3)}
.msel-control[aria-expanded="true"]{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-ring)}
.msel-control .icon{flex:none;color:var(--text-3);transition:transform .15s}
.msel-control[aria-expanded="true"] .icon{transform:rotate(180deg)}
.msel-chips{display:flex;flex-wrap:wrap;gap:5px;flex:1;min-width:0}
.msel-placeholder{color:var(--text-3);font-size:var(--fs-sm,14px)}
/* Count badge on the control, in place of one chip per selection — the chips overflowed
   the bar as soon as a few were ticked. Round, so it reads as a tally rather than a value. */
.msel-count{display:inline-grid;place-items:center;min-width:20px;height:20px;padding:0 6px;
  border-radius:var(--pill);background:var(--primary);color:var(--btn-primary-text,#fff);
  font-size:var(--fs-2xs,11px);font-weight:700;font-family:var(--sans);flex:none;line-height:1}
.msel-count[hidden]{display:none}

/* "Clear all" strip at the top of the open panel. Only rendered while something is
   ticked — see multi-select.js. */
.msel-actions{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:4px 10px 8px;margin-bottom:4px;border-bottom:1px solid var(--border)}
.msel-actions[hidden]{display:none}
.msel-summary{font-size:var(--fs-2xs,11px);color:var(--text-3);font-weight:600;
  letter-spacing:.08em;text-transform:uppercase}
.msel-clear{background:transparent;border:0;padding:0;cursor:pointer;font-family:var(--sans);
  font-size:var(--fs-xs,12px);font-weight:600;color:var(--primary);text-decoration:underline}
.msel-clear:hover{color:var(--primary-700,var(--primary))}
.msel-option{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:8px;font-size:var(--fs-sm,14px);
  color:var(--text-2);cursor:pointer}
.msel-option:hover{background:var(--surface)}
.msel.msel-js .msel-option:hover{background:var(--bg-2)}
.msel-option input[type=checkbox]{width:16px;height:16px;accent-color:var(--primary);flex:none}
/* The type-to-filter sets .hidden on non-matching options, but an author `display:flex`
   beats the browser's own [hidden]{display:none}, so they stayed on screen at full height
   and typing appeared to do nothing. Same fix .csel-panel[hidden] already carries. */
.msel-option[hidden]{display:none}
.msel-panel[hidden]{display:none}
/* Type-to-filter box, injected by public/js/multi-select.js for lists over five options. */
.msel-search{width:100%;background:var(--surface);border:1px solid var(--border);border-radius:8px;
  padding:8px 10px;margin-bottom:4px;color:var(--text);font-size:var(--fs-sm,14px);outline:none}
.msel-search:focus{border-color:var(--primary)}

/* ===== searchable single-select (components/crypto-select.blade.php) =====
   Same visual language as .msel above, but single-pick: clicking an option fills the
   hidden input and closes the panel instead of leaving it open with a checked chip. */
.csel{position:relative}
.csel-control{width:100%;display:flex;align-items:center;justify-content:space-between;gap:8px;
  background:var(--bg-2);border:1px solid var(--border-hi);border-radius:10px;padding:11px 13px;
  min-height:44px;cursor:pointer;font-family:var(--sans);text-align:left}
.csel-control:hover{border-color:var(--text-3)}
.csel-control[aria-expanded="true"]{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-ring)}
.csel-control.is-err{border-color:var(--danger);box-shadow:0 0 0 3px var(--danger-tint)}
.csel-caret{flex:none;color:var(--text-3);transition:transform .15s}
.csel-control[aria-expanded="true"] .csel-caret{transform:rotate(180deg)}
.csel-selected{display:flex;align-items:center;gap:9px;flex:1;min-width:0;font-size:var(--fs-sm,14px);color:var(--text)}
.csel-placeholder{color:var(--text-3)}
.csel-coin-icon{width:20px;height:20px;flex:none;border-radius:50%;overflow:hidden;display:inline-flex}
.csel-coin-icon svg,.csel-coin-icon img{width:100%;height:100%;display:block}
.csel-coin-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.csel-panel{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:60;background:var(--surface);
  border:1px solid var(--border);border-radius:10px;box-shadow:var(--sh-3);padding:6px;
  max-height:300px;display:flex;flex-direction:column}
.csel-panel[hidden]{display:none}
.csel-search-wrap{position:relative;flex:none;margin-bottom:6px}
.csel-search-icon{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--text-3);pointer-events:none}
.csel-search{width:100%;background:var(--bg-2);border:1px solid var(--border-hi);color:var(--text);
  border-radius:8px;padding:8px 10px 8px 32px;font-size:var(--fs-sm,14px);font-family:var(--sans)}
.csel-search:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-ring)}
.csel-options{overflow-y:auto}
.csel-option{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:8px;font-size:var(--fs-sm,14px);
  color:var(--text-2);cursor:pointer}
.csel-option:hover{background:var(--bg-2)}
.csel-option .csel-coin-name{flex:1}
.csel-option .csel-coin-code{color:var(--text-3);font-family:var(--mono);font-size:var(--fs-2xs,11px)}
.csel-msg{padding:14px 10px;text-align:center;font-size:var(--fs-sm,14px);color:var(--text-3)}

.drow{background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-lg);padding:16px 20px;display:flex;align-items:center;gap:18px;
  flex-wrap:wrap;transition:border-color .12s}
.drow:hover{border-color:var(--border-hi)}
/* Featured = an optional black stroke + optional glow tint, same independent admin
   toggles as .dcard.featured, see note there. */
[data-featured-stroke="on"] .drow.featured{border-color:var(--text);border-width:var(--featured-stroke-width,2px)}
[data-card-glow="on"] .drow.featured{background:linear-gradient(100deg,color-mix(in srgb,var(--glow) 16%,var(--surface)),var(--surface) 45%)}
.drow-main{flex:1;min-width:220px;display:flex;flex-direction:column;gap:8px}
.drow-head{display:flex}
.drow-name{display:flex;align-items:center;gap:7px;min-width:0}
.drow-name .drow-star{color:var(--primary-700);width:15px;height:15px;flex:none}
.drow-name .dn{font-family:var(--font-heading);font-weight:700;font-size:var(--fs-lg,19px);letter-spacing:-.01em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.drow-name .dn .tld{color:var(--primary)}
/* The top-right, same-line-as-the-name price is mobile-only — desktop keeps the price
   beside the CTA button (.drow-price-side below), so this stays hidden until the
   max-width:900px block turns it on. */
.drow-price-top{display:none}
.drow-meta{display:flex;gap:8px;flex-wrap:wrap;font-size:var(--fs-xs,12px);color:var(--text-3);align-items:center}
.drow-badges{display:flex;gap:6px;flex-wrap:wrap}
/* Price sits top-right with the CTA button below it. Sized 1.5x the base row/card price
   (18px→27px, BTC line 11px→16.5px) — this is the row's headline number, it should read
   like one. */
.drow-side{display:flex;flex-direction:column;align-items:flex-end;gap:10px;margin-left:auto}
.drow-price{text-align:right;min-width:100px}
.drow-price .k{font-size:var(--fs-2xs,11px);color:var(--text-3)}
.drow-price .v{font-size:var(--fs-2xl,26px);font-weight:700;font-family:var(--font-heading);line-height:1.15}
.drow-price .btc-amount{font-size:calc(var(--fs-2xs,11px) * 1.5)}
.drow-price .btc-amount .icon{width:16px;height:16px}
.drow-cta{flex-shrink:0;min-width:180px;text-align:center;justify-content:center}
@media(max-width:900px){
  .browse-layout{grid-template-columns:1fr}
  .browse-filters{position:static;top:auto}
  /* Price moves up to sit top-right, on the same line as the domain name (.drow-price-top),
     rather than stacked above the button at the bottom — that duplicate (.drow-price-side)
     is hidden here. Sized down slightly from the desktop side price since it now shares a
     line with the name instead of standing alone. */
  .drow-head{justify-content:space-between;align-items:flex-start;gap:12px}
  .drow-price-top{display:block;flex:none;text-align:right}
  .drow-price-top .v{font-size:var(--h3-size,21px);line-height:1.15}
  .drow-price-top .btc-amount{font-size:var(--fs-xs,12px);justify-content:flex-end}
  .drow-price-top .btc-amount .icon{width:12px;height:12px}
  .drow-price-side{display:none}
  /* Only the full-width CTA button remains in the side block on mobile. */
  .drow-side{margin-left:0;width:100%}
  .drow-cta{width:100%;text-align:center;padding:11px 16px}
}

/* ===== hero ===== */
.hero{position:relative;padding:72px 0 48px;text-align:center;overflow:hidden}
/* Off by default (approved v6 direction) — admin can switch on a soft radial glow,
   colour + card-glow tint both driven by the admin-editable --glow swatch. */
[data-bg-glow="on"] .hero::before{content:"";position:absolute;inset:0;z-index:0;
  background:radial-gradient(760px 460px at 12% -15%,color-mix(in srgb,var(--glow) 22%,transparent),transparent 70%),
             radial-gradient(680px 520px at 96% 8%,color-mix(in srgb,var(--glow) 14%,transparent),transparent 65%)}
.hero .wrap{position:relative;z-index:1}
.hero h1{font-family:var(--font-heading);font-size:clamp(36px,6.2vw,var(--h1-size,64px));line-height:1.04;
  font-weight:700;letter-spacing:-.02em;margin:24px 0 16px}
.hero h1 .hl{color:var(--primary-700)}
.hero p.lead{color:var(--text-2);max-width:56ch;margin:0 auto;font-size:var(--fs-lg,19px)}

/* ===== tables ===== */
.tablewrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--r-lg)}
table.data{border-collapse:collapse;width:100%;min-width:640px;font-size:var(--fs-sm,14px)}
table.data thead th{text-align:left;font-size:var(--fs-2xs,11px);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-3);font-weight:600;padding:12px 15px;background:var(--bg-2);border-bottom:1px solid var(--border)}
table.data tbody td{padding:13px 15px;border-bottom:1px solid var(--border);color:var(--text-2)}
table.data tbody tr:hover{background:var(--surface)}
table.data tbody tr:last-child td{border-bottom:0}
.avatar{width:26px;height:26px;border-radius:50%;background:var(--primary);
  display:inline-grid;place-items:center;color:var(--ptext);font-size:11px;font-weight:700;vertical-align:middle;margin-right:6px}

/* ===== stat cards ===== */
.stat{background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-lg);padding:18px}
.stat .k{font-size:var(--fs-xs,12px);color:var(--text-3)}
.stat .v{font-size:var(--fs-2xl,26px);font-weight:780;margin:6px 0 4px;letter-spacing:-.02em}
.stat .d{font-size:var(--fs-xs,12px);font-weight:600}
.up{color:var(--primary)} .down{color:var(--danger)}

/* ===== alerts =====
   Flattened to black/white/grey — only a genuine failure state keeps a colour cue
   (a small red icon), since silently making "payment failed" look identical to
   "settings saved" would be a real usability regression, not just decoration. */
.alert{display:flex;gap:12px;padding:13px 15px;border-radius:var(--r);border:1px solid var(--border-hi);
  font-size:var(--fs-sm,14px);margin-bottom:12px;background:var(--bg);color:var(--text)}
.alert .ai{flex:none;font-weight:800;color:var(--text)}

/* ===== shared inline-SVG icon set (replaces emoji everywhere — consistent rendering,
   no dependence on the OS/browser's emoji font) — see components/icon.blade.php ===== */
.icon{flex:none;vertical-align:-3px}
a.nav .icon, .btn .icon{vertical-align:-3px}
.a-ok{}
.a-info{}
.a-warn{}
.a-err .ai{color:var(--danger)}
.a-err{border-color:color-mix(in srgb,var(--danger) 35%,var(--border-hi))}

/* ===== acquisition card — one card, one radio list, one action (nquiz.com pattern) ===== */
.acq-card{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);overflow:hidden}
.acq-card-head{padding:20px 22px 2px}
.acq-card-head h2{font-size:var(--fs-lg,19px);margin:0 0 6px}
.acq-card-head p{color:var(--text-2);font-size:var(--fs-sm,14px);margin:0 0 4px}
.acq-opt{border-top:1px solid var(--border);padding:15px 22px;cursor:pointer}
.acq-opt:hover{background:var(--bg-2)}
.acq-opt.is-selected{background:var(--bg-2);cursor:default}
.acq-opt-row{display:flex;align-items:center;gap:13px}
.acq-opt input[type=radio]{width:19px;height:19px;accent-color:var(--primary);flex:none;margin:0}
.acq-opt-label{flex:1;font-weight:700;font-size:var(--fs-sm,14px);display:flex;align-items:center;gap:7px}
.acq-opt-label .sub{font-weight:500;color:var(--text-3);font-size:var(--fs-xs,12px)}
.acq-opt-price{text-align:right;font-family:var(--font-heading)}
.acq-opt-price b{color:var(--primary);font-size:var(--fs-sm,14px);font-weight:700}
.acq-opt-price .permo{color:var(--text-3);font-size:var(--fs-2xs,11px);display:block}
.acq-reveal{margin-top:14px;padding-left:32px}
/* Optional website add-on. Full width rather than inheriting .acq-reveal's 32px indent —
   it's a second thing to buy, not a setting belonging to the row above — and tinted so it
   reads as an offer instead of fine print under the price. */
.acq-reveal.acq-addon{padding:13px 15px;border:1px solid var(--primary);border-radius:var(--r);
  background:var(--primary-tint)}
.acq-addon-pick{display:flex;align-items:flex-start;gap:11px;cursor:pointer}
.acq-addon-pick input[type=checkbox]{width:18px;height:18px;accent-color:var(--primary);flex:none;margin:1px 0 0}
.acq-addon-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.acq-addon-head b{font-size:var(--fs-sm,14px)}
.acq-addon-price{color:var(--primary);font-weight:700;font-size:var(--fs-sm,14px);white-space:nowrap;
  font-family:var(--font-heading)}
.acq-addon-note{display:block;margin-top:3px;color:var(--text-2);font-size:var(--fs-xs,12px);line-height:1.45}
.acq-addon-total{display:flex;align-items:baseline;justify-content:space-between;
  margin-top:11px;padding-top:10px;border-top:1px solid var(--border-hi);
  font-weight:700;font-size:var(--fs-sm,14px);font-family:var(--font-heading)}
.acq-reveal input.input, .acq-reveal textarea.input{background:var(--bg)}

/* lease term slider */
.lease-box{border:1px solid var(--border-hi);border-radius:var(--r);padding:14px 16px;display:flex}
.lease-box .col{flex:1;padding:0 4px}
.lease-box .col+.col{border-left:1px solid var(--border-hi);padding-left:16px;margin-left:4px}
.lease-box .k{font-size:var(--fs-xs,12px);color:var(--text-2)}
.lease-box .v{font-size:var(--fs-lg,19px);font-weight:700;margin-top:2px}
.lease-slider{width:100%;margin:16px 0 10px;accent-color:var(--primary)}
.commission-range{width:100%;margin:6px 0 4px;accent-color:var(--primary)}
.lease-term-note{font-size:var(--fs-sm,14px)}
.lease-term-note b{font-weight:700}
.lease-more{font-size:var(--fs-xs,12px);color:var(--text-2);text-decoration:underline;text-underline-offset:2px}

.acq-next{border-top:1px solid var(--border);padding:18px 22px 22px}
.acq-trust{padding:2px 22px 22px}
.acq-trust ul{list-style:none;margin:14px 0 0;padding:0;display:flex;flex-direction:column;gap:8px}
.acq-trust li{display:flex;align-items:center;gap:9px;font-size:var(--fs-sm,14px);color:var(--text-2)}
.acq-trust li svg{flex:none;color:var(--text)}
/* Admin-uploaded payment-provider logo strip (Fiat / Crypto). Static row when everything
   fits; JS adds .marquee + duplicates the content for a seamless infinite scroll only
   when the logos actually overflow the available width. */
.logo-row{overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 20px,#000 calc(100% - 20px),transparent);
  mask-image:linear-gradient(90deg,transparent,#000 20px,#000 calc(100% - 20px),transparent)}
.logo-track{display:flex;align-items:center;gap:10px;width:max-content}
.logo-track.marquee{animation:logo-scroll linear infinite}
.logo-track.marquee:hover{animation-play-state:paused}
.logo-chip{flex:none;height:20px;max-width:76px;object-fit:contain;border:1px solid var(--border-hi);
  border-radius:6px;padding:5px 9px;background:var(--bg)}
/* Payment method with no logo uploaded — same row, a plain text chip instead of an icon. */
.logo-chip-text{flex:none;height:20px;display:inline-flex;align-items:center;white-space:nowrap;
  font-size:var(--fs-2xs,11px);font-weight:600;color:var(--text-2);border:1px solid var(--border-hi);
  border-radius:6px;padding:0 9px;background:var(--bg)}
/* Logo chips carry their name as a tooltip (hover on desktop, tap on touch — see the
   .paylogo-wrap click handler in the script block below) instead of always showing text. */
.paylogo-wrap{position:relative;display:inline-flex;flex:none}
.paylogo-wrap .paylogo-tip{position:absolute;bottom:100%;left:50%;transform:translateX(-50%) translateY(-4px);
  background:var(--text);color:var(--bg);font-size:var(--fs-2xs,11px);font-weight:600;padding:3px 8px;border-radius:6px;
  white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .12s;z-index:5}
.paylogo-wrap:hover .paylogo-tip,.paylogo-wrap:focus .paylogo-tip,.paylogo-wrap.is-tapped .paylogo-tip{opacity:1}
@keyframes logo-scroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* Small explainer popover (components/info-tip.blade.php) — a modern card instead of the
   plain browser title="" tooltip it replaced. --tip-shift is nudged by the component's own
   script when the centered position would otherwise overflow the viewport, so it always
   stays fully on-screen instead of running off the edge of a narrow panel. */
.info-tip{position:relative;display:inline-flex;align-items:center;color:var(--text-3);
  cursor:help;vertical-align:middle;--tip-shift:0px}
.info-tip:hover,.info-tip:focus,.info-tip.is-tapped{color:var(--text-2)}
.info-tip:focus{outline:none}
.info-tip-panel{position:absolute;left:50%;bottom:calc(100% + 10px);
  transform:translateX(calc(-50% + var(--tip-shift))) translateY(4px);
  width:max-content;max-width:230px;background:var(--surface);color:var(--text);
  border:1px solid var(--border-hi);border-radius:var(--r,14px);box-shadow:var(--sh-3);
  padding:11px 14px;font-size:var(--fs-xs,12px);font-weight:500;line-height:1.55;text-align:left;
  opacity:0;visibility:hidden;pointer-events:none;transition:opacity .15s ease,transform .15s ease;z-index:30}
.info-tip:hover .info-tip-panel,.info-tip:focus .info-tip-panel,.info-tip.is-tapped .info-tip-panel{
  opacity:1;visibility:visible;transform:translateX(calc(-50% + var(--tip-shift))) translateY(0)}
.info-tip-panel::before{content:"";position:absolute;top:100%;left:calc(50% - var(--tip-shift));
  transform:translateX(-50%);border:6px solid transparent;border-top-color:var(--border-hi)}
.info-tip-panel::after{content:"";position:absolute;top:100%;left:calc(50% - var(--tip-shift));
  transform:translateX(-50%) translateY(-1px);border:5px solid transparent;border-top-color:var(--surface)}
@media(prefers-reduced-motion:reduce){.info-tip-panel{transition:none}}
@media(prefers-reduced-motion:reduce){.logo-track.marquee{animation:none;overflow-x:auto}}

/* ===== misc ===== */
.perk{display:flex;align-items:center;justify-content:space-between;background:var(--bg-2);
  border:1px solid var(--border);border-radius:10px;padding:12px 14px}
/* Auto-fit so 1 perk fills the row, 2 split it, 3+ wrap — never leaves dead columns. */
.perk-grid{display:grid;gap:14px;margin-top:8px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.verify-step{display:flex;gap:13px;padding:13px 0;border-bottom:1px solid var(--border)}
.verify-step:last-child{border-bottom:0}
.vnum{width:26px;height:26px;border-radius:8px;background:var(--primary-tint);color:var(--primary);
  display:grid;place-items:center;font-size:13px;font-weight:700;flex:none}
.site-foot{padding:40px 0 60px;background:var(--footer-bg);color:var(--footer-text);font-size:var(--fs-sm,14px);border-top:1px solid var(--border);margin-top:48px}
.site-foot .faint{color:color-mix(in srgb,var(--footer-text) 70%,transparent)}
.footer-grid{display:flex;flex-wrap:wrap;gap:32px 48px;align-items:flex-start}
.footer-brand{flex:1 1 220px;min-width:200px}
.footer-col{display:flex;flex-direction:column;gap:9px;min-width:110px}
.footer-col-title{font-weight:700;color:var(--footer-text);text-transform:uppercase;letter-spacing:.04em;font-size:var(--fs-xs,12px);margin-bottom:2px}
/* Phone: stop the columns squeezing into narrow strips — each block takes the full width
   and stacks, so link lists stay readable and tappable. */
@media(max-width:700px){
  .footer-grid{flex-direction:column;gap:24px}
  .footer-brand,.footer-col{flex:1 1 auto;width:100%;min-width:0}
}
code.k{font-family:var(--mono);font-size:var(--fs-xs,12px);background:var(--bg-2);border:1px solid var(--border);
  padding:2px 6px;border-radius:6px;color:var(--primary)}
.section-title{font-size:var(--h2-size,24px);font-weight:750;margin-bottom:6px}

/* ===== admin shell ===== */
.admin{display:grid;grid-template-columns:232px 1fr;min-height:100vh}
/* Grid items default to min-width:auto, which respects a child's intrinsic minimum size
   (e.g. a wide data table) instead of letting it scroll within .tablewrap — this is what
   was stretching the whole grid sideways on mobile. min-width:0 lets .admin-main shrink
   below that intrinsic width so .tablewrap's own overflow-x:auto can actually contain it. */
.admin-main{min-width:0}
.admin-side{background:var(--bg-2);border-right:1px solid var(--border);padding:18px 14px;
  display:flex;flex-direction:column;gap:4px;position:sticky;top:0;height:100vh;overflow-y:auto}
.admin-side .brand{padding:6px 10px 16px}
.admin-side a.nav{display:flex;align-items:center;gap:10px;font-size:var(--fs-sm,14px);color:var(--text-2);
  padding:9px 12px;border-radius:9px;font-weight:550}
.admin-side a.nav:hover{background:var(--surface);color:var(--text)}
.admin-side a.nav.active{background:var(--primary-tint);color:var(--primary)}
.admin-side .sep{height:1px;background:var(--border);margin:10px 4px}
/* Sidebar section headers — same uppercase-caption idiom as .lbl used elsewhere
   (payment-method group headers, panel captions), just sized down for the nav rail. */
.admin-side .group-label{font-size:var(--fs-2xs,11px);font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-3);padding:14px 12px 2px;margin:0}
.admin-side .group-label:first-of-type{padding-top:6px}
/* Settings' own tab list, contextually shown only while inside Settings (see the
   route check in admin.blade.php) — clicking a sub-item jumps straight to that tab. */
.admin-side .nav-sub{display:flex;flex-direction:column;gap:1px;margin:2px 0 4px 28px}
.admin-side .nav-sub a{font-size:var(--fs-xs,12px);color:var(--text-3);padding:6px 10px;border-radius:7px;font-weight:500}
.admin-side .nav-sub a:hover{background:var(--surface);color:var(--text)}
.admin-side .nav-sub a.active{background:var(--primary-tint);color:var(--primary);font-weight:650}
/* Group headings inside the settings sub-nav — quieter than .group-label since they sit
   one level deeper again. */
.admin-side .nav-sub-label{font-size:var(--fs-2xs,11px);font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-3);padding:8px 10px 2px;opacity:.75}
.admin-side .nav-sub-label:first-child{padding-top:2px}
.admin-main{padding:28px 32px;width:100%}
.admin-main .pagehead{display:flex;align-items:center;justify-content:space-between;gap:16px;
  margin-bottom:22px;flex-wrap:wrap}
.admin-main .pagehead h1{font-size:var(--h3-size,21px);font-weight:750}
/* The mobile menu's own bits — the checkbox and top bar only exist below the breakpoint. */
.admin-nav-toggle,.admin-topbar{display:none}

@media(max-width:860px){
  .admin{grid-template-columns:1fr}
  /* A real collapsible menu now, not a wrapping row of 25 chips with the group headings
     switched off. Pure CSS off the checkbox above, so it works with JS disabled. */
  .admin-topbar{display:flex;align-items:center;justify-content:space-between;gap:12px;
    padding:10px 14px;background:var(--bg-2);border-bottom:1px solid var(--border);
    position:sticky;top:0;z-index:40}
  .admin-topbar .brand{padding:0}
  .admin-nav-btn{display:inline-flex;align-items:center;justify-content:center;position:relative;
    width:38px;height:38px;border:1px solid var(--border-hi);border-radius:9px;
    background:var(--surface);color:var(--text);cursor:pointer;flex:none}
  .admin-nav-btn .notif-badge{top:-4px;right:-4px}
  .admin-side{position:static;height:auto;max-height:0;overflow:hidden;padding:0 12px;
    border-right:0;border-bottom:1px solid var(--border);gap:1px;
    transition:max-height .2s ease,padding .2s ease}
  /* The sidebar's own brand is redundant once the top bar shows one. */
  .admin-side-brand{display:none}
  .admin-nav-toggle:checked ~ .admin-side{max-height:85vh;overflow-y:auto;padding:10px 12px 14px}
  .admin-side a.nav{padding:10px 12px;font-size:var(--fs-sm,14px)}
  .admin-side .group-label{padding:12px 12px 2px}
  .admin-side .nav-sub{margin:2px 0 4px 20px}
  .admin-main{padding:20px 16px}
}
@media(prefers-reduced-motion:reduce){.admin-side{transition:none}}
.filterbar{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:16px}
.filterbar .input,.filterbar .select{width:auto;min-width:160px}
/* Ranked insight lists (admin/search-logs) — a proportional bar behind each row so the
   biggest driver of a report reads at a glance, not just as a number to compare by eye. */
.rank-row{position:relative;display:flex;align-items:center;justify-content:space-between;
  gap:8px;padding:6px 8px;border-radius:8px;margin-bottom:2px;overflow:hidden}
.rank-bar{position:absolute;left:0;top:0;bottom:0;background:var(--primary-tint);z-index:0;border-radius:8px}
.rank-label{position:relative;z-index:1;font-size:var(--fs-sm,14px);color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-decoration:none}
a.rank-label:hover{text-decoration:underline}
.rank-count{position:relative;z-index:1;font-size:var(--fs-xs,12px);font-weight:700;color:var(--text-2);flex:none}
/* The raw count beside each percentage — kept visible for sample size (a headline "50%"
   off two searches isn't worth posting) but quieter, since the percentage is the figure
   these panels exist to surface. */
.rank-n{font-weight:600;color:var(--text-3)}
.zero-row{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:6px 0;border-bottom:1px solid var(--border);font-size:var(--fs-sm,14px)}
.zero-row:last-child{border-bottom:0}
.actions{display:flex;gap:6px;align-items:center}
.actions form{margin:0}
.swatch-input{display:flex;align-items:center;gap:10px;background:var(--bg-2);
  border:1px solid var(--border);border-radius:10px;padding:8px 10px}
.swatch-input input[type=color]{width:34px;height:30px;border:0;background:transparent;padding:0;cursor:pointer}
.swatch-input .nm{font-size:var(--fs-xs,12px);font-weight:600;flex:1}
.swatch-input .cur{font-family:var(--mono);font-size:var(--fs-2xs,11px);color:var(--text-3)}
.tabnav{display:flex;gap:6px;border-bottom:1px solid var(--border);margin-bottom:20px;flex-wrap:wrap}
.tabnav a{font-size:var(--fs-sm,14px);font-weight:600;color:var(--text-2);padding:9px 14px;border-radius:9px 9px 0 0}
.tabnav a.active{color:var(--primary);box-shadow:inset 0 -2px 0 var(--primary)}
.tabnav a:hover{color:var(--text)}
/* Settings' tab strip is eleven tabs long — grouping them keeps it scannable instead of
   one undifferentiated row, and keeps each group together when the row wraps. */
.tabnav-grouped{gap:0 18px;align-items:flex-end}
.tabnav-group{display:flex;align-items:flex-end;flex-wrap:wrap;gap:2px;position:relative;padding-top:18px}
.tabnav-group-label{position:absolute;top:0;left:6px;font-size:var(--fs-2xs,11px);font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--text-3);white-space:nowrap}
/* Hairline between groups, so they read as distinct clusters without a heavy divider. */
.tabnav-group+.tabnav-group::before{content:"";position:absolute;left:-9px;top:20px;bottom:6px;
  width:1px;background:var(--border)}
@media(max-width:640px){
  .tabnav-grouped{gap:0 12px}
  .tabnav-grouped a{padding:8px 10px;font-size:var(--fs-xs,12px)}
}
.checkline{display:flex;align-items:center;gap:10px;font-size:var(--fs-sm,14px);padding:10px 0;
  border-bottom:1px solid var(--border)}
.checkline:last-child{border-bottom:0}
/* Scoped to DIRECT checkbox/radio children only — a .toggle-wrapped checkbox is nested one
   level deeper (inside .toggle span), so it's untouched here and keeps its own 100%/100%
   sizing instead of being shrunk to this native 18px box (that specificity clash used to
   leave the toggle's real, clickable input tiny and mispositioned under its visual slider). */
.checkline>input[type=checkbox],.checkline>input[type=radio]{width:18px;height:18px;accent-color:var(--primary);flex:none}
.checkline .grow{flex:1}

/* Toggle switch — a checkbox wrapped visually. Kept as a plain <span> (not <label>) so it
   nests inside an existing .checkline <label> without illegal nested-label markup; the
   surrounding label already associates with the input since it's still a descendant. */
.toggle{position:relative;display:inline-block;width:38px;height:22px;flex:none}
/* z-index above .slider so the invisible input is the actual hit target for a direct click,
   rather than relying solely on native <label> click-forwarding from the slider below it. */
.toggle input{position:absolute;z-index:1;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.toggle .slider{position:absolute;inset:0;background:var(--border-hi);border-radius:999px;
  transition:background .15s ease}
.toggle .slider::before{content:'';position:absolute;width:16px;height:16px;left:3px;top:3px;
  background:var(--surface);border-radius:50%;transition:transform .15s ease;box-shadow:0 1px 2px rgba(0,0,0,.3)}
/* Brand green for the "on" state — reads clearly against both the light and dark palette
   (var(--text) used to fill this role, but in dark mode --text is near-white, which put a
   near-white track behind a white thumb with almost no contrast between the two). */
.toggle input:checked+.slider{background:var(--primary)}
.toggle input:checked+.slider::before{transform:translateX(16px);background:#fff}
.toggle input:focus-visible+.slider{outline:2px solid var(--primary);outline-offset:2px}

/* Type-to-confirm delete modal — shared across the admin, opened by any
   [data-confirm-delete] trigger (see the script in layouts/admin.blade.php). */
.modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.55);display:flex;
  align-items:center;justify-content:center;z-index:1000;padding:20px}
.modal-overlay[hidden]{display:none}
.modal-box{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:26px;max-width:440px;width:100%;box-shadow:var(--sh-3)}
.modal-box h3{margin:0 0 10px;font-size:var(--fs-lg,19px);display:flex;align-items:center;gap:8px;color:var(--danger)}
.modal-box .modal-phrase{font-family:var(--mono);background:var(--surface-2);border:1px solid var(--border-hi);
  border-radius:6px;padding:1px 7px;color:var(--text)}

.form-cols{display:grid;grid-template-columns:repeat(2,1fr);gap:0 18px}
@media(max-width:700px){.form-cols{grid-template-columns:1fr}}
fieldset.group{border:1px solid var(--border);border-radius:var(--r);padding:16px 18px;margin:0 0 18px}
fieldset.group legend{font-size:var(--fs-2xs,11px);font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-3);padding:0 6px}

/* ===== collapsible payment-provider accordion (admin Settings > Payments) =====
   Each provider is a <details>; the summary row (name + on/off + configured badges) stays
   visible, and the whole key/fee configuration collapses behind it. */
.provider-box{border:1px solid var(--border);border-radius:var(--r);margin:0 0 12px;overflow:hidden}
.provider-box[open]{border-color:var(--border-hi)}
.provider-summary{display:flex;align-items:center;gap:10px;padding:14px 16px;cursor:pointer;
  list-style:none;font-size:var(--fs-sm,14px);user-select:none}
.provider-summary::-webkit-details-marker{display:none}
.provider-summary::after{content:"";flex:none;width:8px;height:8px;margin-left:4px;
  border-right:2px solid var(--text-3);border-bottom:2px solid var(--text-3);
  transform:rotate(45deg);transition:transform .18s}
.provider-box[open] .provider-summary::after{transform:rotate(-135deg)}
.provider-summary:hover{background:var(--bg-2)}
.provider-summary .grow{flex:1;min-width:0}
.provider-body{padding:2px 16px 16px;border-top:1px solid var(--border)}

/* ===== homepage trust strip ===== */
.trust-strip{display:flex;align-items:center;gap:18px;flex-wrap:wrap;justify-content:space-between}
.trust-lead{display:flex;align-items:flex-start;gap:12px;min-width:min(100%,320px);flex:1 1 320px}
.trust-lead .hint{margin-top:2px;max-width:52ch}
.trust-ico{flex:none;display:grid;place-items:center;width:40px;height:40px;border-radius:12px;
  background:var(--primary-tint);color:var(--primary)}
.trust-methods{display:flex;flex-wrap:wrap;gap:8px}
.trust-chip{display:inline-flex;align-items:center;gap:7px;padding:8px 13px;border-radius:999px;
  border:1px solid var(--border-hi);background:var(--surface-hi);color:var(--text-2);
  font-size:var(--fs-sm,14px);font-weight:600;white-space:nowrap}

/* "Save all changes" bar on admin pages built from per-row forms. Sticks to the bottom of
   the viewport, and only ever appears once something has actually been edited. */
.bulk-save-bar{position:sticky;bottom:16px;z-index:60;display:flex;align-items:center;gap:12px;
  margin:20px 0 0;padding:12px 16px;border-radius:var(--r);
  background:var(--surface);border:1px solid var(--primary);
  box-shadow:0 10px 30px -8px rgba(0,0,0,.28)}
.bulk-save-bar[hidden]{display:none}
.bulk-save-count{font-weight:700;font-size:var(--fs-sm,14px);color:var(--text)}
.bulk-save-status{flex:1;font-size:var(--fs-sm,14px);color:var(--text-2)}
/* Edited-but-unsaved rows get a quiet marker so it's obvious what the bar is about to send. */
form[data-bulk-save].is-dirty{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-ring)}
@media(max-width:700px){
  .bulk-save-bar{flex-wrap:wrap;bottom:8px}
  .bulk-save-status{flex:1 1 100%;order:3}
}

/* Segmented term switch (fixed period vs lifetime) on the package checkout + pricing page.
   Real radios underneath so it works without JS and is keyboard/screen-reader native. */
.term-switch{display:flex;gap:4px;padding:4px;background:var(--bg-2);
  border:1px solid var(--border);border-radius:var(--r);flex-wrap:wrap}
.term-switch label{flex:1 1 160px;margin:0}
.term-switch input{position:absolute;opacity:0;width:0;height:0}
.term-switch span{display:block;text-align:center;padding:9px 12px;border-radius:var(--r-sm);
  font-size:var(--fs-sm,14px);font-weight:600;color:var(--text-2);cursor:pointer;transition:.15s ease}
.term-switch input:checked + span{background:var(--surface);color:var(--text);
  box-shadow:0 1px 3px rgba(0,0,0,.1)}
.term-switch input:focus-visible + span{outline:2px solid var(--primary);outline-offset:2px}

/* A copy-me command line (admin Cron page). Scrolls rather than wrapping — a wrapped cron
   line looks like two commands and gets pasted wrong. */
.codeblock{font-family:var(--mono);font-size:var(--fs-xs,12px);line-height:1.6;color:var(--text);
  background:var(--bg-2);border:1px solid var(--border);border-radius:var(--r);
  padding:12px 14px;margin:0;overflow-x:auto;white-space:pre;-webkit-user-select:all;user-select:all}

/* ===== mobile bottom app bar ===== */
.mobile-nav{display:none}
.filter-trigger,.sheet-head,.sheet-overlay{display:none}
@media(max-width:900px){
  .mobile-nav{position:fixed;left:0;right:0;bottom:0;z-index:500;
    display:grid;grid-auto-flow:column;grid-auto-columns:1fr;align-items:end;
    background:var(--surface);border-top:1px solid var(--border);
    padding:7px 6px calc(7px + env(safe-area-inset-bottom))}
  .mnav-item{display:flex;flex-direction:column;align-items:center;gap:3px;
    color:var(--text-3);font-size:var(--fs-2xs,11px);font-weight:600;text-decoration:none;padding:2px 0}
  .mnav-item.is-active{color:var(--primary-700)}
  .mnav-item .icon{flex:none}
  /* Raised centre Sell action */
  .mnav-sell{color:var(--text-2)}
  .mnav-sell-btn{display:grid;place-items:center;width:46px;height:46px;margin-top:-22px;
    border-radius:50%;background:var(--btn-primary-bg);color:var(--btn-primary-text);
    box-shadow:0 6px 16px rgba(0,0,0,.18);border:3px solid var(--surface)}
  /* Opposite corner from .notif-badge (top-right) so the two never collide */
  .mnav-level-badge{position:absolute;bottom:-3px;right:-5px;width:14px;height:14px;
    border-radius:50%;background:var(--surface);border:1.5px solid var(--surface);
    display:grid;place-items:center;font-size:9px;line-height:1;pointer-events:none}
  /* Keep page content clear of the fixed bar */
  body:has(.mobile-nav) main{padding-bottom:72px}
  body:has(.mobile-nav) .site-foot{padding-bottom:84px}

  /* Full-width card CTA */
  .dcard .foot .btn{padding:11px 16px}

  /* Browse: single full-width Filter trigger; the form becomes a bottom sheet once JS
     tags it .as-sheet (no-JS keeps the inline form). */
  .filter-trigger{display:flex;align-items:center;justify-content:center;gap:8px}
  .browse-filters.as-sheet{position:fixed;left:0;right:0;bottom:0;z-index:710;margin:0;
    border-radius:var(--r-lg) var(--r-lg) 0 0;border-bottom:0;max-height:82vh;overflow-y:auto;
    padding:16px 18px calc(18px + env(safe-area-inset-bottom));
    transform:translateY(105%);transition:transform .28s cubic-bezier(.32,.72,.35,1);
    box-shadow:0 -14px 44px rgba(0,0,0,.24)}
  .browse-filters.as-sheet.is-open{transform:none}
  .browse-filters.as-sheet .sheet-head{display:flex;align-items:center;justify-content:space-between;
    margin-bottom:12px;font-size:var(--body-size,16px)}
  .sheet-x{display:grid;place-items:center;width:32px;height:32px;border-radius:50%;
    border:1px solid var(--border);background:var(--surface-2);color:var(--text-2);cursor:pointer}
  .sheet-overlay:not([hidden]){display:block;position:fixed;inset:0;z-index:705;background:rgba(0,0,0,.45)}
  body.sheet-locked{overflow:hidden}
}
@media(prefers-reduced-motion:reduce){.browse-filters.as-sheet{transition:none}}

/* ===== auth "or" divider (between the Google button and the email/password form) ===== */
.auth-divider{display:flex;align-items:center;gap:12px;margin:16px 0;color:var(--text-3);
  font-size:var(--fs-xs,12px);text-transform:uppercase;letter-spacing:.06em}
.auth-divider::before,.auth-divider::after{content:"";flex:1;height:1px;background:var(--border)}

/* ===== trust seal (House / iGamingDomains-sold domains) ===== */
/* Sized to its content (+padding) — never stretched by a flex parent, never truncated;
   wraps onto a second line in narrow columns instead of ellipsizing. A <button> that opens
   the shared #trust-modal, so the reset (border/font) is part of the look. */
.trust-seal{display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:999px;
  border:0;font-family:inherit;text-align:left;
  background:var(--primary-tint);color:var(--primary-700);font-size:var(--fs-xs,12px);font-weight:700;
  line-height:1.25;cursor:pointer;max-width:100%;align-self:flex-start;width:fit-content}
.trust-seal:hover{background:var(--primary-ring)}
.trust-seal:focus-visible{outline:none;box-shadow:0 0 0 3px var(--primary-ring)}

/* Trust modal — same overlay/box system as the admin delete modal, calmer palette. */
.trust-modal{max-width:420px}
.trust-modal h3{color:var(--text)}
.trust-modal .trust-modal-ico{display:grid;place-items:center;width:46px;height:46px;
  border-radius:14px;background:var(--primary-tint);color:var(--primary);margin-bottom:12px}
.trust-modal-lead{margin:0;color:var(--text-2);font-size:var(--fs-sm,14px);line-height:1.55}
.trust-modal-list{list-style:none;margin:14px 0 18px;padding:0;display:grid;gap:9px}
.trust-modal-list li{display:flex;align-items:flex-start;gap:9px;font-size:var(--fs-sm,14px);color:var(--text-2)}
.trust-modal-list .icon{flex:none;margin-top:2px;color:var(--primary)}
.trust-seal .trust-seal-ico{display:inline-flex;flex:none;color:var(--primary)}
.trust-seal-sm{padding:3px 9px;font-size:var(--fs-2xs,11px);gap:5px}

/* ===== payment methods on domain cards ===== */
.pay-methods{display:flex;align-items:center;flex-wrap:wrap;gap:5px;margin-top:8px}
.pay-methods-lbl{font-size:var(--fs-2xs,11px);color:var(--text-3);font-weight:600;margin-right:1px}
.pay-chip{display:inline-flex;align-items:center;padding:2px 7px;border-radius:6px;
  border:1px solid var(--border);background:var(--surface-2);color:var(--text-2);
  font-size:var(--fs-2xs,11px);font-weight:600;line-height:1.4;text-decoration:none;transition:filter .12s}
a.pay-chip:hover{filter:brightness(.94)}
/* Category name(s) in a card/row's meta line, now linking to that category's browse page. */
.meta-link{color:inherit;text-decoration:underline;text-decoration-color:var(--border-hi);
  text-underline-offset:2px;transition:text-decoration-color .12s}
.meta-link:hover{text-decoration-color:var(--text-2)}

/* ===== inline save toast (admin perks) ===== */
.perk-toast{position:fixed;right:20px;bottom:20px;z-index:600;max-width:340px;
  background:var(--btn-primary-bg);color:var(--btn-primary-text);
  padding:12px 16px;border-radius:var(--r);box-shadow:0 8px 24px rgba(0,0,0,.18);
  font-size:var(--fs-sm,14px);font-weight:600}
.perk-toast.is-err{background:var(--danger);color:#fff}
@media (prefers-reduced-motion:no-preference){
  .perk-toast{animation:perkToastIn .18s ease-out}
}
@keyframes perkToastIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ===== level progress bar ===== */
/* The track's own background is a fixed gradient from the current level's color to the
   next level's — the mask (page-surface-colored, right-anchored) simply covers however
   much of that gradient the user HASN'T reached yet, so the visible fill blends from one
   level's color toward the other exactly as far as real progress warrants. */
.level-progress{position:relative;height:10px;border-radius:999px;overflow:hidden}
.level-progress-mask{position:absolute;top:0;right:0;bottom:0;background:var(--surface)}

/* ===== escrow progress ladder ===== */
.escrow-track{border:1px solid var(--border);border-radius:var(--r);padding:12px 14px;background:var(--surface-2)}
.escrow-step{display:flex;align-items:center;gap:10px;padding:6px 0;color:var(--text-3);font-size:var(--fs-sm,14px)}
.escrow-step .grow{flex:1}
.escrow-dot{flex:none;width:11px;height:11px;border-radius:50%;border:2px solid var(--border-hi);background:var(--surface)}
.escrow-step.done{color:var(--text-2)}
.escrow-step.done .escrow-dot{background:var(--primary);border-color:var(--primary)}
.escrow-step.now{color:var(--text);font-weight:600}
.escrow-step.now .escrow-dot{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-ring)}

/* ===== wizard step indicator ===== */
.wizard-steps{display:flex;align-items:center;margin-bottom:26px}
.wstep{display:flex;align-items:center;gap:9px;flex:none}
.wstep .wdot{width:28px;height:28px;border-radius:50%;background:var(--surface-hi);color:var(--text-3);
  display:grid;place-items:center;font-size:12.5px;font-weight:700;border:1px solid var(--border-hi);
  flex:none;transition:.15s}
.wstep .wlabel{font-size:var(--fs-xs,12px);color:var(--text-3);font-weight:600;white-space:nowrap;transition:.15s}
.wstep.active .wdot{background:var(--primary);color:var(--ptext);border-color:var(--primary)}
.wstep.active .wlabel{color:var(--text)}
.wstep.done .wdot{background:var(--primary-tint);color:var(--primary);border-color:var(--primary)}
.wstep.done .wlabel{color:var(--text-2)}
.wline{flex:1;height:2px;background:var(--border-hi);margin:0 10px;min-width:16px;transition:.15s}
.wline.done{background:var(--primary)}
@media(max-width:640px){.wstep .wlabel{display:none}}

.badge-lg{padding:9px 16px;font-size:var(--fs-sm,14px);border-radius:12px;gap:8px}

/* ===== rich text content (admin-authored pages: Terms, Privacy, etc.) ===== */
.page-content h2{font-size:var(--h3-size,21px);font-weight:700;margin:28px 0 12px;color:var(--text)}
.page-content h2:first-child{margin-top:0}
.page-content h3{font-size:var(--body-size,16px);font-weight:700;margin:20px 0 8px;color:var(--text)}
.page-content p{margin:0 0 14px;color:var(--text-2)}
.page-content ul,.page-content ol{margin:0 0 14px;padding-left:22px;color:var(--text-2)}
.page-content li{margin-bottom:6px}
.page-content a{color:var(--primary);text-decoration:underline}
.page-content strong{color:var(--text);font-weight:600}
.page-content hr{border:0;border-top:1px solid var(--border);margin:24px 0}

.pagination{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.pagination-pages{display:flex;align-items:center;gap:4px;flex-wrap:wrap}
.pagination-dots{color:var(--text-3);padding:0 4px;font-size:var(--fs-sm,14px)}
.pagination .btn-sm{min-width:36px;justify-content:center}

/* Affiliate payout progress toward the minimum (affiliate/dashboard) — a plain track so
   a referrer can see how close they are without reading two numbers and doing the maths. */
.payout-track{height:8px;border-radius:999px;background:var(--surface-2);border:1px solid var(--border);overflow:hidden}
.payout-fill{height:100%;background:var(--primary);border-radius:999px;transition:width .2s ease}
@media(prefers-reduced-motion:reduce){.payout-fill{transition:none}}

/* Dashboard promo banner (free-listing allowance) — tinted rather than alert-coloured:
   it's good news, not a warning, and the alert palette is spoken for by real problems. */
.promo-banner{display:flex;align-items:center;gap:14px;padding:14px 16px;border-radius:var(--r,14px);
  border:1px solid color-mix(in srgb,var(--primary) 35%,transparent);background:var(--primary-tint)}
.promo-banner .grow{flex:1;min-width:0}
.promo-banner-ico{display:inline-grid;place-items:center;width:38px;height:38px;flex:none;
  border-radius:10px;background:var(--surface);color:var(--primary)}
.promo-banner-x{background:none;border:0;padding:6px;cursor:pointer;color:var(--text-3);
  border-radius:8px;flex:none;line-height:0}
.promo-banner-x:hover{background:var(--surface);color:var(--text)}
.promo-banner[hidden]{display:none}
@media(max-width:560px){.promo-banner{flex-wrap:wrap}.promo-banner .grow{flex:1 1 100%;order:2}}

/* Vertical tab rail for long admin section lists (components/admin-tabs.blade.php).
   Replaced flat wrapping .tabnav rows that reached 25 links on the email-template page. */
.admin-tabs{display:grid;grid-template-columns:224px minmax(0,1fr);gap:22px;align-items:start}
.admin-tabs-body{min-width:0}
.admin-tab-rail{display:flex;flex-direction:column;gap:1px;position:sticky;top:20px;
  max-height:calc(100vh - 40px);overflow-y:auto;padding-right:4px}
.admin-tab-rail a{font-size:var(--fs-sm,14px);font-weight:550;color:var(--text-2);
  padding:8px 11px;border-radius:8px;line-height:1.35;text-decoration:none}
.admin-tab-rail a:hover{background:var(--surface-2);color:var(--text)}
.admin-tab-rail a.active{background:var(--primary-tint);color:var(--primary);font-weight:700}
.admin-tab-rail-label{font-size:var(--fs-2xs,11px);font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-3);padding:14px 11px 3px}
.admin-tab-rail-label:first-child{padding-top:2px}
/* The rail is desktop-only; a phone gets the native picker instead. */
.admin-tabs-picker{display:none}
@media(max-width:900px){
  .admin-tabs{grid-template-columns:1fr;gap:16px}
  .admin-tab-rail{display:none}
  .admin-tabs-picker{display:block}
  .admin-tabs-picker .lbl{display:block;margin-bottom:6px}
}
