/* ==========================================================================
   NEXUS STYLESHEET — hand-owned as of 2026-08-22. Tailwind is gone.
   No build step, no safelist, no config. This block is the source: edit it
   directly. (History: last compiled from Tailwind v3.4.19 on 2026-08-19;
   the detach was a formatting-only transform, verified two ways — re-minifying
   this block reproduces the original blob byte-for-byte, and the parsed CSSOM
   was diffed rule-by-rule against the previous build. See LEDGER.md.)

   THE RULES
   1. A class does nothing unless a rule for it exists here. New class =>
      write the rule yourself, at the end, with a semantic name.
   2. Never build class names at runtime (bg-${...}, w-[${...}%]). Computed
      values go in style="..." or a custom property. The composed colour
      classes (bg|text|border)-(mtg-*|nexus-*) in the pip/bar templates keep
      working only because their rules are baked in below (ex-safelist) —
      do not extend that pattern to new code.
   3. This block must stay AFTER the components \3c style> block above:
      utility rules here beat .magic-glass etc. on source order, matching
      the old CDN-injection cascade.
   4. Do not re-sort the inherited rules. Order is load-bearing.

   A handful of junk selectors below (.bg-\[url\(\'\$\{imgA\}...) are
   fossils: the old scanner read unresolved template literals as class names.
   They match nothing. Left in place to keep this block a provable transform
   of the last compiled output; delete them freely if they ever get in the way.

   TOKENS: since 2026-09-03 every colour is rgb(var(--nx-*)) — see the COLOUR
   TOKENS block just below the preamble for the names, the dark values, the
   light values and the accent overrides. The old hex list (base #080b12,
   surface #101623, blue #00E1FF, …) is the DARK column of that block. Never
   write a new colour as a literal: pick a token, or add one to the block
   with both a dark and a light value.
   ========================================================================== */
/* === Tailwind-era var preamble: required by the transform / shadow / ring / filter rules below === */
*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }
/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/
/* ==========================================================================
   COLOUR TOKENS — added 2026-09-03 (Chad approved the light/dark theme and the
   accent picker). Before this the stylesheet held ZERO colour custom
   properties: every colour below was a baked literal, so a light theme was
   impossible without rewriting 3,800 lines. The migration was mechanical
   (scratchpad/tokenise.py): each literal became rgb(var(--nx-*)) with the
   alpha syntax Tailwind compiled (`/var(--tw-bg-opacity,1)`) left untouched.
   Channel triplets, not hex, for exactly that reason.

   THREE LAYERS, in cascade order:
     1. bare :root            = DARK, the design this app was drawn in.
     2. prefers-color-scheme  = light when the OS says so and the user has
                                not chosen (no data-theme stamp).
     3. :root[data-theme]     = the user's explicit choice, wins both ways.
   Then [data-accent] re-points --nx-accent (and the ink that sits on it).
   The stamp is written before first paint by the inline script in
   src/layouts/Base.astro and kept by src/scripts/modules/26-theme.js.

   RULES for these tokens:
   - Never give a colour its only definition inside a theme block. Every
     token is declared on bare :root first.
   - --nx-ink is what .text-white resolves to. An element with a solid
     coloured fill re-declares --nx-ink:255 255 255 on itself (see the
     on-colour block near the end of this file) so a badge keeps white text
     in the light theme too.
   - --nx-hair is the translucent white hairline (border-white/10 & co.);
     it flips to a translucent dark hairline on a light ground.
   - Semantic tones (error/warning/success/violet) and the MTG colour set
     are NOT the accent and do not follow the picker.
   ========================================================================== */
:root{
  --nx-base:8 11 18;            /* #080b12 page ground */
  --nx-surface:16 22 35;        /* #101623 panels */
  --nx-surface-alt:21 25 35;    /* #151923 */
  --nx-surface-hover:23 30 45;  /* #171e2d hover / borders */
  --nx-track:42 52 65;          /* #2a3441 bars, meters */
  --nx-card:15 23 42;           /* #0f172a slate-900: glass, drawers */
  --nx-dark:2 6 23;             /* #020617 slate-950: hero fades */
  --nx-text:248 250 252;        /* #f8fafc */
  --nx-ink:255 255 255;         /* .text-white */
  --nx-muted:148 163 184;       /* #94a3b8 */
  --nx-hair:255 255 255;        /* translucent hairlines, used with an alpha */
  --nx-accent:0 225 255;        /* #00e1ff Nexus cyan — re-pointed by [data-accent] */
  --nx-accent-ink:8 11 18;      /* text sitting on a solid accent fill */
  /* What a solid button's hover mixes TOWARD. It must be the opposite of
     --nx-accent-ink: lightening a fill under white text destroys contrast,
     which is exactly the bug measured 2026-09-06. Flipped per theme below. */
  --nx-accent-ink-hover:255 255 255;
  --nx-violet:124 58 237;       /* #7c3aed */
  --nx-violet-lit:167 139 250;  /* #a78bfa */
  --nx-error:225 29 72;         /* #e11d48 */
  --nx-error-lit:251 113 133;   /* #fb7185 */
  --nx-warning:217 119 6;       /* #d97706 */
  --nx-success:5 150 105;       /* #059669 -- the TINT (text on dark, 4.80) */
  --nx-success-deep:4 120 87;   /* #047857 -- the FILL under white text (5.48).
                                   #059669 under white is 3.77 and fails AA. */
  --nx-success-lit:52 211 153;  /* #34d399 */
  --nx-common:148 163 184;      /* rarity */
  --nx-uncommon:96 165 250;
  --nx-rare:251 191 36;         /* also the lit warning gold */
  --nx-mythic:249 115 22;
  --nx-special:232 121 249;     /* #e879f9 — added 2026-09-03, was unmapped */
  --nx-bonus:45 212 191;        /* #2dd4bf — added 2026-09-03, was unmapped */
  --nx-slate-100:241 245 249;   /* the ex-Tailwind grey ramp; inverted in light */
  --nx-slate-200:226 232 240;
  --nx-slate-300:203 213 225;
  --nx-slate-500:100 116 139;
  --nx-slate-600:71 85 105;
  --nx-slate-700:51 65 85;
  --nx-slate-800:30 41 59;
  --nx-mtg-w:248 231 185;       /* printed-card palette, pips and bars */
  --nx-mtg-u:179 206 234;
  --nx-mtg-b:166 159 157;
  --nx-mtg-r:235 159 130;
  --nx-mtg-g:196 211 202;
  --nx-mtg-c:204 204 204;
  color-scheme:dark;
}
/* Light values. Declared once as a mixin-by-copy in the two places the
   cascade needs them (the OS preference and the explicit stamp); keep the two
   blocks identical. */
@media (prefers-color-scheme:light){
  :root:not([data-theme="dark"]){
    --nx-base:244 246 250;
    --nx-surface:255 255 255;
    --nx-surface-alt:238 242 247;
    --nx-surface-hover:226 232 240;
    --nx-track:203 213 225;
    --nx-card:255 255 255;
    --nx-dark:244 246 250;
    --nx-text:11 18 32;
    --nx-ink:11 18 32;
    --nx-muted:71 85 105;
    --nx-hair:15 23 42;
    /* #00748f, not #0087a6. The light themes put WHITE ink on the accent
       (--nx-accent-ink below), and #0087a6 under white is 4.19 -- under the
       4.5 AA bar both as a fill and as tinted text. Measured 2026-09-06. */
    --nx-accent:0 116 143;
    --nx-accent-ink:255 255 255;
    --nx-accent-ink-hover:0 0 0;
    --nx-violet:109 40 217;
    --nx-violet-lit:109 40 217;
    --nx-error:190 18 60;
    --nx-error-lit:190 18 60;
    --nx-warning:180 83 9;
    --nx-success:4 120 87;
    --nx-success-lit:4 120 87;
    --nx-common:71 85 105;
    --nx-uncommon:29 78 216;
    --nx-rare:161 98 7;
    --nx-mythic:234 88 12;
    --nx-special:162 28 175;
    --nx-bonus:15 118 110;
    --nx-slate-100:15 23 42;
    --nx-slate-200:30 41 59;
    --nx-slate-300:51 65 85;
    --nx-slate-500:100 116 139;
    --nx-slate-600:148 163 184;
    --nx-slate-700:203 213 225;
    --nx-slate-800:226 232 240;
    --nx-mtg-w:138 109 31;
    --nx-mtg-u:47 111 174;
    --nx-mtg-b:91 85 82;
    --nx-mtg-r:194 81 44;
    --nx-mtg-g:60 122 74;
    --nx-mtg-c:107 107 107;
    color-scheme:light;
  }
}
:root[data-theme="light"]{
    --nx-base:244 246 250;
    --nx-surface:255 255 255;
    --nx-surface-alt:238 242 247;
    --nx-surface-hover:226 232 240;
    --nx-track:203 213 225;
    --nx-card:255 255 255;
    --nx-dark:244 246 250;
    --nx-text:11 18 32;
    --nx-ink:11 18 32;
    --nx-muted:71 85 105;
    --nx-hair:15 23 42;
    /* #00748f, not #0087a6. The light themes put WHITE ink on the accent
       (--nx-accent-ink below), and #0087a6 under white is 4.19 -- under the
       4.5 AA bar both as a fill and as tinted text. Measured 2026-09-06. */
    --nx-accent:0 116 143;
    --nx-accent-ink:255 255 255;
    --nx-accent-ink-hover:0 0 0;
    --nx-violet:109 40 217;
    --nx-violet-lit:109 40 217;
    --nx-error:190 18 60;
    --nx-error-lit:190 18 60;
    --nx-warning:180 83 9;
    --nx-success:4 120 87;
    --nx-success-lit:4 120 87;
    --nx-common:71 85 105;
    --nx-uncommon:29 78 216;
    --nx-rare:161 98 7;
    --nx-mythic:234 88 12;
    --nx-special:162 28 175;
    --nx-bonus:15 118 110;
    --nx-slate-100:15 23 42;
    --nx-slate-200:30 41 59;
    --nx-slate-300:51 65 85;
    --nx-slate-500:100 116 139;
    --nx-slate-600:148 163 184;
    --nx-slate-700:203 213 225;
    --nx-slate-800:226 232 240;
    --nx-mtg-w:138 109 31;
    --nx-mtg-u:47 111 174;
    --nx-mtg-b:91 85 82;
    --nx-mtg-r:194 81 44;
    --nx-mtg-g:60 122 74;
    --nx-mtg-c:107 107 107;
    color-scheme:light;
}
/* An explicit dark choice on a light OS: restate only what the light media
   block would otherwise override. The values are the bare :root ones. */
:root[data-theme="dark"]{color-scheme:dark}

/* ACCENTS — six, each with a dark and a light value. Nexus Cyan is the
   default and needs no stamp. The dark ink is right for every dark-theme
   accent except ruby; every light-theme accent is deep enough for white ink. */
:root[data-accent="violet"]{--nx-accent:167 139 250}
:root[data-accent="blue"]  {--nx-accent:96 165 250}
:root[data-accent="green"] {--nx-accent:74 222 128}
/* Ruby carried --nx-accent-ink:255 255 255. White on #f0524b is 3.49, and the
   hover lightened it to 2.95 -- the worst contrast in the system, measured
   2026-09-06. The default dark ink gives 5.64 rest / 6.67 hover and leaves the
   tint at 5.18, so ruby simply inherits it. */
:root[data-accent="ruby"]  {--nx-accent:240 82 75}
:root[data-accent="gold"]  {--nx-accent:251 191 36}
@media (prefers-color-scheme:light){
  :root:not([data-theme="dark"])[data-accent="violet"]{--nx-accent:109 40 217}
  :root:not([data-theme="dark"])[data-accent="blue"]  {--nx-accent:29 78 216}
  :root:not([data-theme="dark"])[data-accent="green"] {--nx-accent:18 128 90}
  :root:not([data-theme="dark"])[data-accent="ruby"]  {--nx-accent:198 45 38}
  :root:not([data-theme="dark"])[data-accent="gold"]  {--nx-accent:161 98 7}
}
:root[data-theme="light"][data-accent="violet"]{--nx-accent:109 40 217}
:root[data-theme="light"][data-accent="blue"]  {--nx-accent:29 78 216}
:root[data-theme="light"][data-accent="green"] {--nx-accent:18 128 90}
:root[data-theme="light"][data-accent="ruby"]  {--nx-accent:198 45 38}
:root[data-theme="light"][data-accent="gold"]  {--nx-accent:161 98 7}

/* === Base reset (ex-preflight) === */
*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}
:after,:before{--tw-content:""}
:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,ui-sans-serif,system-ui,-apple-system,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}
body{margin:0;line-height:inherit}
hr{height:0;color:inherit;border-top-width:1px}
abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}
h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}
a{color:inherit;text-decoration:inherit}
b,strong{font-weight:bolder}
code,kbd,pre,samp{font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}
sub{bottom:-.25em}
sup{top:-.5em}
table{text-indent:0;border-color:inherit;border-collapse:collapse}
button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}
button,select{text-transform:none}
button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:initial;background-image:none}
:-moz-focusring{outline:auto}
:-moz-ui-invalid{box-shadow:none}
progress{vertical-align:initial}
::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}
[type=search]{-webkit-appearance:textfield;outline-offset:-2px}
::-webkit-search-decoration{-webkit-appearance:none}
::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}
summary{display:list-item}
blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}
fieldset{margin:0}
fieldset,legend{padding:0}
menu,ol,ul{list-style:none;margin:0;padding:0}
dialog{padding:0}
textarea{resize:vertical}
input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:rgb(var(--nx-muted))}
input::placeholder,textarea::placeholder{opacity:1;color:rgb(var(--nx-muted))}
[role=button],button{cursor:pointer}
:disabled{cursor:default}
audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}
img,video{max-width:100%;height:auto}
[hidden]:where(:not([hidden=until-found])){display:none}
/* === Utilities (inherited JIT output order — do not re-sort; new rules go at the very end) === */
.\!container{width:100%!important}
.container{width:100%}
/* === Responsive variants === */
/* === sm: @media (min-width:640px) === */
@media (min-width:640px){
  .\!container{max-width:640px!important}
  .container{max-width:640px}
}
/* === md: @media (min-width:768px) === */
@media (min-width:768px){
  .\!container{max-width:768px!important}
  .container{max-width:768px}
}
/* === lg: @media (min-width:1024px) === */
@media (min-width:1024px){
  .\!container{max-width:1024px!important}
  .container{max-width:1024px}
}
/* === xl: @media (min-width:1280px) === */
@media (min-width:1280px){
  .\!container{max-width:1280px!important}
  .container{max-width:1280px}
}
/* === 2xl: @media (min-width:1536px) === */
@media (min-width:1536px){
  .\!container{max-width:1536px!important}
  .container{max-width:1536px}
}
.pointer-events-none{pointer-events:none}
.pointer-events-auto{pointer-events:auto}
.visible{visibility:visible}
.collapse{visibility:collapse}
.static{position:static}
.fixed{position:fixed}
.absolute{position:absolute}
.relative{position:relative}
.sticky{position:sticky}
.inset-0{inset:0}
.inset-y-0{top:0;bottom:0}
.-left-2{left:-.5rem}
.-left-3{left:-.75rem}
.-right-1\.5{right:-.375rem}
.-right-10{right:-2.5rem}
.-right-2{right:-.5rem}
.-right-3{right:-.75rem}
.-top-1\.5{top:-.375rem}
.-top-10{top:-2.5rem}
.-top-2{top:-.5rem}
.-top-2\.5{top:-.625rem}
.-top-3{top:-.75rem}
.bottom-0{bottom:0}
.bottom-1{bottom:.25rem}
.bottom-4{bottom:1rem}
.bottom-6{bottom:1.5rem}
.bottom-\[76px\]{bottom:76px}
.left-0{left:0}
.left-1\.5{left:.375rem}
.left-1\/2{left:50%}
.left-2{left:.5rem}
.left-3{left:.75rem}
.left-4{left:1rem}
.left-6{left:1.5rem}
.left-\[-10\%\]{left:-10%}
.left-\[5\.5\%\]{left:5.5%}
.right-0{right:0}
.right-1{right:.25rem}
.right-1\.5{right:.375rem}
.right-2{right:.5rem}
.right-4{right:1rem}
.right-6{right:1.5rem}
.right-\[-10\%\]{right:-10%}
.top-0{top:0}
.top-1{top:.25rem}
.top-1\.5{top:.375rem}
.top-1\/2{top:50%}
.top-10{top:2.5rem}
.top-2{top:.5rem}
.top-4{top:1rem}
.top-6{top:1.5rem}
.top-8{top:2rem}
.top-\[-10\%\]{top:-10%}
.top-\[100\%\]{top:100%}
.top-\[110\%\]{top:110%}
.top-\[260px\]{top:260px}
.top-\[3\.5\%\]{top:3.5%}
.top-\[40\%\]{top:40%}
.top-\[68px\]{top:68px}
.isolate{isolation:isolate}
.z-0{z-index:0}
.z-10{z-index:10}
.z-20{z-index:20}
.z-30{z-index:30}
.z-40{z-index:40}
.z-50{z-index:50}
.z-\[100\]{z-index:100}
.z-\[110\]{z-index:110}
.z-\[120\]{z-index:120}
.z-\[130\]{z-index:130}
.z-\[140\]{z-index:140}
.z-\[200\]{z-index:200}
.z-\[210\]{z-index:210}
.z-\[90\]{z-index:90}
.z-\[95\]{z-index:95}
.z-\[9999\]{z-index:9999}
.col-span-1{grid-column:span 1/span 1}
.col-span-full{grid-column:1/-1}
.m-2{margin:.5rem}
.mx-1{margin-left:.25rem;margin-right:.25rem}
.mx-1\.5{margin-left:.375rem;margin-right:.375rem}
.mx-\[0\.5px\]{margin-left:.5px;margin-right:.5px}
.mx-\[1px\]{margin-left:1px;margin-right:1px}
.mx-auto{margin-left:auto;margin-right:auto}
.my-1{margin-top:.25rem;margin-bottom:.25rem}
.-mt-\[115\%\]{margin-top:-115%}
.mb-0\.5{margin-bottom:.125rem}
.mb-1{margin-bottom:.25rem}
.mb-1\.5{margin-bottom:.375rem}
.mb-12{margin-bottom:3rem}
.mb-2{margin-bottom:.5rem}
.mb-3{margin-bottom:.75rem}
.mb-4{margin-bottom:1rem}
.mb-5{margin-bottom:1.25rem}
.mb-6{margin-bottom:1.5rem}
.mb-8{margin-bottom:2rem}
.ml-1{margin-left:.25rem}
.ml-1\.5{margin-left:.375rem}
.ml-2{margin-left:.5rem}
.ml-4{margin-left:1rem}
.ml-auto{margin-left:auto}
.mr-1{margin-right:.25rem}
.mr-1\.5{margin-right:.375rem}
.mr-2{margin-right:.5rem}
.mt-0\.5{margin-top:.125rem}
.mt-1{margin-top:.25rem}
.mt-1\.5{margin-top:.375rem}
.mt-2{margin-top:.5rem}
.mt-3{margin-top:.75rem}
.mt-4{margin-top:1rem}
.mt-6{margin-top:1.5rem}
.mt-8{margin-top:2rem}
.mt-\[-4px\]{margin-top:-4px}
.mt-auto{margin-top:auto}
.line-clamp-1{-webkit-line-clamp:1}
.line-clamp-1,.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical}
.line-clamp-2{-webkit-line-clamp:2}
.block{display:block}
.inline-block{display:inline-block}
.inline{display:inline}
.flex{display:flex}
.inline-flex{display:inline-flex}
.table{display:table}
.\!grid{display:grid!important}
.grid{display:grid}
.hidden{display:none}
.aspect-\[2\/3\]{aspect-ratio:2/3}
.aspect-\[3\/4\]{aspect-ratio:3/4}
.aspect-\[5\/7\]{aspect-ratio:5/7}
.aspect-square{aspect-ratio:1/1}
.aspect-video{aspect-ratio:16/9}
.h-1{height:.25rem}
.h-1\.5{height:.375rem}
.h-10{height:2.5rem}
.h-12{height:3rem}
.h-14{height:3.5rem}
.h-16{height:4rem}
.h-2{height:.5rem}
.h-20{height:5rem}
.h-3{height:.75rem}
.h-3\.5{height:.875rem}
.h-32{height:8rem}
.h-4{height:1rem}
.h-44{height:11rem}
.h-48{height:12rem}
.h-5{height:1.25rem}
.h-6{height:1.5rem}
.h-64{height:16rem}
.h-7{height:1.75rem}
.h-72{height:18rem}
.h-8{height:2rem}
.h-80{height:20rem}
.h-9{height:2.25rem}
.h-96{height:24rem}
.h-\[14px\]{height:14px}
.h-\[150px\]{height:150px}
.h-\[154px\]{height:154px}
.h-\[1px\]{height:1px}
.h-\[220px\]{height:220px}
.h-\[340px\]{height:340px}
.h-\[3px\]{height:3px}
.h-\[45\%\]{height:45%}
.h-\[450px\]{height:450px}
.h-\[60vh\]{height:60vh}
.h-\[72px\]{height:72px}
.h-\[80vh\]{height:80vh}
.h-\[85vh\]{height:85vh}
.h-\[90vh\]{height:90vh}
.h-\[var\(--bar-height\)\]{height:var(--bar-height)}
.h-auto{height:auto}
.h-full{height:100%}
.h-px{height:1px}
.max-h-64{max-height:16rem}
.max-h-\[160px\]{max-height:160px}
.max-h-\[400px\]{max-height:400px}
.max-h-\[40vh\]{max-height:40vh}
.max-h-\[700px\]{max-height:700px}
.max-h-\[85vh\]{max-height:85vh}
.max-h-\[90vh\]{max-height:90vh}
.min-h-0{min-height:0}
.min-h-\[2px\]{min-height:2px}
.min-h-\[400px\]{min-height:400px}
.min-h-\[450px\]{min-height:450px}
.min-h-\[4px\]{min-height:4px}
.min-h-\[50vh\]{min-height:50vh}
.min-h-\[600px\]{min-height:600px}
.min-h-screen{min-height:100vh}
.w-0{width:0}
.w-1{width:.25rem}
.w-1\.5{width:.375rem}
.w-1\/2{width:50%}
.w-10{width:2.5rem}
.w-12{width:3rem}
.w-14{width:3.5rem}
.w-16{width:4rem}
.w-2{width:.5rem}
.w-20{width:5rem}
.w-24{width:6rem}
.w-3{width:.75rem}
.w-3\.5{width:.875rem}
.w-32{width:8rem}
.w-4{width:1rem}
.w-44{width:11rem}
.w-48{width:12rem}
.w-5{width:1.25rem}
.w-6{width:1.5rem}
.w-64{width:16rem}
.w-7{width:1.75rem}
.w-8{width:2rem}
.w-80{width:20rem}
.w-9{width:2.25rem}
.w-96{width:24rem}
.w-\[110px\]{width:110px}
.w-\[140px\]{width:140px}
.w-\[14px\]{width:14px}
.w-\[150px\]{width:150px}
.w-\[154px\]{width:154px}
.w-\[1px\]{width:1px}
.w-\[220px\]{width:220px}
.w-\[340px\]{width:340px}
.w-\[3px\]{width:3px}
.w-\[580px\]{width:580px}
.w-\[90\%\]{width:90%}
.w-full{width:100%}
.w-max{width:-moz-max-content;width:max-content}
.w-px{width:1px}
.min-w-0{min-width:0}
.min-w-\[200px\]{min-width:200px}
.min-w-\[220px\]{min-width:220px}
.min-w-\[30px\]{min-width:30px}
.min-w-\[340px\]{min-width:340px}
.max-w-2xl{max-width:42rem}
.max-w-3xl{max-width:48rem}
.max-w-4xl{max-width:56rem}
.max-w-5xl{max-width:64rem}
.max-w-7xl{max-width:80rem}
.max-w-\[100px\]{max-width:100px}
.max-w-\[1600px\]{max-width:1600px}
.max-w-\[1800px\]{max-width:1800px}
.max-w-\[2280px\]{max-width:2280px}
.max-w-\[260px\]{max-width:260px}
.max-w-\[280px\]{max-width:280px}
.max-w-\[32px\]{max-width:32px}
.max-w-\[450px\]{max-width:450px}
.max-w-\[50\%\]{max-width:50%}
.max-w-\[90vw\]{max-width:90vw}
.max-w-md{max-width:28rem}
.max-w-sm{max-width:24rem}
.flex-1{flex:1 1 0%}
.shrink{flex-shrink:1}
.shrink-0{flex-shrink:0}
.-translate-x-1\/2{--tw-translate-x:-50%}
.-translate-x-1\/2,.-translate-x-24{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.-translate-x-24{--tw-translate-x:-6rem}
.-translate-y-1\/2{--tw-translate-y:-50%}
.-translate-y-1\/2,.-translate-y-2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.-translate-y-2{--tw-translate-y:-0.5rem}
.-translate-y-4{--tw-translate-y:-1rem}
.-translate-y-4,.translate-x-2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.translate-x-2{--tw-translate-x:0.5rem}
.translate-x-24{--tw-translate-x:6rem}
.translate-x-24,.translate-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.translate-y-0{--tw-translate-y:0px}
.translate-y-4{--tw-translate-y:1rem}
.-rotate-12,.translate-y-4{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.-rotate-12{--tw-rotate:-12deg}
.-rotate-90{--tw-rotate:-90deg}
.-rotate-90,.rotate-12{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.rotate-12{--tw-rotate:12deg}
.rotate-3{--tw-rotate:3deg}
.rotate-3,.scale-110{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.scale-110{--tw-scale-x:1.1;--tw-scale-y:1.1}
.scale-95{--tw-scale-x:.95;--tw-scale-y:.95}
.scale-95,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.animate-\[pulse_1\.5s_ease-in-out_infinite\]{animation:pulse 1.5s ease-in-out infinite}
.animate-\[pulse_3s_ease-in-out_infinite\]{animation:pulse 3s ease-in-out infinite}
@keyframes bounce{0%,to{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}
.animate-bounce{animation:bounce 1s infinite}
@keyframes pulse{50%{opacity:.5}}
.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}
@keyframes pulseGlow{0%,to{opacity:.3;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}
.animate-pulse-glow{animation:pulseGlow 4s ease-in-out infinite}
@keyframes spin{to{transform:rotate(1turn)}}
.animate-spin{animation:spin 1s linear infinite}
.cursor-help{cursor:help}
.cursor-not-allowed{cursor:not-allowed}
.cursor-pointer{cursor:pointer}
.cursor-text{cursor:text}
.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}
.resize-none{resize:none}
.resize{resize:both}
.snap-x{scroll-snap-type:x var(--tw-scroll-snap-strictness)}
.snap-start{scroll-snap-align:start}
.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}
.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}
.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.flex-row{flex-direction:row}
.flex-col{flex-direction:column}
.flex-wrap{flex-wrap:wrap}
.items-start{align-items:flex-start}
.items-end{align-items:flex-end}
.items-center{align-items:center}
.justify-start{justify-content:flex-start}
.justify-end{justify-content:flex-end}
.justify-center{justify-content:center}
.justify-between{justify-content:space-between}
.gap-1{gap:.25rem}
.gap-1\.5{gap:.375rem}
.gap-10{gap:2.5rem}
.gap-12{gap:3rem}
.gap-2{gap:.5rem}
.gap-2\.5{gap:.625rem}
.gap-3{gap:.75rem}
.gap-3\.5{gap:.875rem}
.gap-4{gap:1rem}
.gap-5{gap:1.25rem}
.gap-6{gap:1.5rem}
.gap-8{gap:2rem}
.gap-\[-30px\]{gap:-30px}
.gap-\[0\.5px\]{gap:.5px}
.gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}
.gap-y-2{row-gap:.5rem}
.-space-x-12>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(-3rem*var(--tw-space-x-reverse));margin-left:calc(-3rem*(1 - var(--tw-space-x-reverse)))}
.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}
.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.75rem*var(--tw-space-x-reverse));margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)))}
.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}
.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem*var(--tw-space-y-reverse))}
.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}
.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}
.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}
.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem*var(--tw-space-y-reverse))}
.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}
.divide-nexus-surface>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(var(--nx-surface)/var(--tw-divide-opacity,1))}
.divide-nexus-surface-hover>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(var(--nx-surface-hover)/var(--tw-divide-opacity,1))}
.self-center{align-self:center}
.overflow-hidden{overflow:hidden}
.overflow-visible{overflow:visible}
.overflow-x-auto{overflow-x:auto}
.overflow-y-auto{overflow-y:auto}
.overflow-x-hidden{overflow-x:hidden}
.truncate{overflow:hidden;white-space:nowrap}
.text-ellipsis,.truncate{text-overflow:ellipsis}
.whitespace-nowrap{white-space:nowrap}
.break-words{overflow-wrap:break-word}
.rounded{border-radius:.25rem}
.rounded-2xl{border-radius:1rem}
.rounded-3xl,.rounded-\[1\.5rem\]{border-radius:1.5rem}
.rounded-\[15px\]{border-radius:15px}
.rounded-\[2rem\]{border-radius:2rem}
.rounded-full{border-radius:9999px}
.rounded-lg{border-radius:.5rem}
.rounded-xl{border-radius:.75rem}
.rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}
.rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}
.rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}
.rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}
.rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}
.rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}
.border{border-width:1px}
.border-2{border-width:2px}
.border-4{border-width:4px}
.border-b{border-bottom-width:1px}
.border-b-2{border-bottom-width:2px}
.border-l{border-left-width:1px}
.border-l-2{border-left-width:2px}
.border-l-4{border-left-width:4px}
.border-r{border-right-width:1px}
.border-t{border-top-width:1px}
.border-t-2{border-top-width:2px}
.border-dashed{border-style:dashed}
.border-dotted{border-style:dotted}
.border-brand-cardkingdom\/30{border-color:#eab3084d}
.border-brand-tcgplayer\/30{border-color:#16a34a4d}
.border-mtg-b{--tw-border-opacity:1;border-color:rgb(var(--nx-mtg-b)/var(--tw-border-opacity,1))}
.border-mtg-b\/10{border-color:rgb(var(--nx-mtg-b)/0.1)}
.border-mtg-b\/20{border-color:rgb(var(--nx-mtg-b)/0.2)}
.border-mtg-b\/30{border-color:rgb(var(--nx-mtg-b)/0.3)}
.border-mtg-b\/40{border-color:rgb(var(--nx-mtg-b)/0.4)}
.border-mtg-b\/50{border-color:rgb(var(--nx-mtg-b)/0.5)}
.border-mtg-b\/60{border-color:rgb(var(--nx-mtg-b)/0.6)}
.border-mtg-b\/70{border-color:rgb(var(--nx-mtg-b)/0.7)}
.border-mtg-b\/80{border-color:rgb(var(--nx-mtg-b)/0.8)}
.border-mtg-b\/90{border-color:rgb(var(--nx-mtg-b)/0.9)}
.border-mtg-c{--tw-border-opacity:1;border-color:rgb(var(--nx-mtg-c)/var(--tw-border-opacity,1))}
.border-mtg-c\/10{border-color:rgb(var(--nx-mtg-c)/0.1)}
.border-mtg-c\/20{border-color:rgb(var(--nx-mtg-c)/.2)}
.border-mtg-c\/30{border-color:rgb(var(--nx-mtg-c)/0.3)}
.border-mtg-c\/40{border-color:rgb(var(--nx-mtg-c)/.4)}
.border-mtg-c\/50{border-color:rgb(var(--nx-mtg-c)/0.5)}
.border-mtg-c\/60{border-color:rgb(var(--nx-mtg-c)/.6)}
.border-mtg-c\/70{border-color:rgb(var(--nx-mtg-c)/0.7)}
.border-mtg-c\/80{border-color:rgb(var(--nx-mtg-c)/.8)}
.border-mtg-c\/90{border-color:rgb(var(--nx-mtg-c)/0.9)}
.border-mtg-g{--tw-border-opacity:1;border-color:rgb(var(--nx-mtg-g)/var(--tw-border-opacity,1))}
.border-mtg-g\/10{border-color:rgb(var(--nx-mtg-g)/0.1)}
.border-mtg-g\/20{border-color:rgb(var(--nx-mtg-g)/0.2)}
.border-mtg-g\/30{border-color:rgb(var(--nx-mtg-g)/0.3)}
.border-mtg-g\/40{border-color:rgb(var(--nx-mtg-g)/0.4)}
.border-mtg-g\/50{border-color:rgb(var(--nx-mtg-g)/0.5)}
.border-mtg-g\/60{border-color:rgb(var(--nx-mtg-g)/0.6)}
.border-mtg-g\/70{border-color:rgb(var(--nx-mtg-g)/0.7)}
.border-mtg-g\/80{border-color:rgb(var(--nx-mtg-g)/0.8)}
.border-mtg-g\/90{border-color:rgb(var(--nx-mtg-g)/0.9)}
.border-mtg-r{--tw-border-opacity:1;border-color:rgb(var(--nx-mtg-r)/var(--tw-border-opacity,1))}
.border-mtg-r\/10{border-color:rgb(var(--nx-mtg-r)/0.1)}
.border-mtg-r\/20{border-color:rgb(var(--nx-mtg-r)/0.2)}
.border-mtg-r\/30{border-color:rgb(var(--nx-mtg-r)/0.3)}
.border-mtg-r\/40{border-color:rgb(var(--nx-mtg-r)/0.4)}
.border-mtg-r\/50{border-color:rgb(var(--nx-mtg-r)/0.5)}
.border-mtg-r\/60{border-color:rgb(var(--nx-mtg-r)/0.6)}
.border-mtg-r\/70{border-color:rgb(var(--nx-mtg-r)/0.7)}
.border-mtg-r\/80{border-color:rgb(var(--nx-mtg-r)/0.8)}
.border-mtg-r\/90{border-color:rgb(var(--nx-mtg-r)/0.9)}
.border-mtg-u{--tw-border-opacity:1;border-color:rgb(var(--nx-mtg-u)/var(--tw-border-opacity,1))}
.border-mtg-u\/10{border-color:rgb(var(--nx-mtg-u)/0.1)}
.border-mtg-u\/20{border-color:rgb(var(--nx-mtg-u)/0.2)}
.border-mtg-u\/30{border-color:rgb(var(--nx-mtg-u)/0.3)}
.border-mtg-u\/40{border-color:rgb(var(--nx-mtg-u)/0.4)}
.border-mtg-u\/50{border-color:rgb(var(--nx-mtg-u)/0.5)}
.border-mtg-u\/60{border-color:rgb(var(--nx-mtg-u)/0.6)}
.border-mtg-u\/70{border-color:rgb(var(--nx-mtg-u)/0.7)}
.border-mtg-u\/80{border-color:rgb(var(--nx-mtg-u)/0.8)}
.border-mtg-u\/90{border-color:rgb(var(--nx-mtg-u)/0.9)}
.border-mtg-w{--tw-border-opacity:1;border-color:rgb(var(--nx-mtg-w)/var(--tw-border-opacity,1))}
.border-mtg-w\/10{border-color:rgb(var(--nx-mtg-w)/0.1)}
.border-mtg-w\/20{border-color:rgb(var(--nx-mtg-w)/0.2)}
.border-mtg-w\/30{border-color:rgb(var(--nx-mtg-w)/0.3)}
.border-mtg-w\/40{border-color:rgb(var(--nx-mtg-w)/0.4)}
.border-mtg-w\/50{border-color:rgb(var(--nx-mtg-w)/0.5)}
.border-mtg-w\/60{border-color:rgb(var(--nx-mtg-w)/0.6)}
.border-mtg-w\/70{border-color:rgb(var(--nx-mtg-w)/0.7)}
.border-mtg-w\/80{border-color:rgb(var(--nx-mtg-w)/0.8)}
.border-mtg-w\/90{border-color:rgb(var(--nx-mtg-w)/0.9)}
.border-nexus-base{--tw-border-opacity:1;border-color:rgb(var(--nx-base)/var(--tw-border-opacity,1))}
.border-nexus-blue{--tw-border-opacity:1;border-color:rgb(var(--nx-accent)/var(--tw-border-opacity,1))}
.border-nexus-blue\/30{border-color:rgb(var(--nx-accent)/0.3)}
.border-nexus-blue\/40{border-color:rgb(var(--nx-accent)/0.4)}
.border-nexus-blue\/50{border-color:rgb(var(--nx-accent)/0.5)}
.border-nexus-blue\/60{border-color:rgb(var(--nx-accent)/0.6)}
.border-nexus-blue\/70{border-color:rgb(var(--nx-accent)/0.7)}
.border-nexus-border{--tw-border-opacity:1;border-color:rgb(var(--nx-surface-hover)/var(--tw-border-opacity,1))}
.border-nexus-card{--tw-border-opacity:1;border-color:rgb(var(--nx-card)/var(--tw-border-opacity,1))}
.border-nexus-common{--tw-border-opacity:1;border-color:rgb(var(--nx-muted)/var(--tw-border-opacity,1))}
.border-nexus-dark{--tw-border-opacity:1;border-color:rgb(var(--nx-dark)/var(--tw-border-opacity,1))}
.border-nexus-error{--tw-border-opacity:1;border-color:rgb(var(--nx-error)/var(--tw-border-opacity,1))}
.border-nexus-error\/30{border-color:rgb(var(--nx-error)/0.3)}
.border-nexus-error\/40{border-color:rgb(var(--nx-error)/0.4)}
.border-nexus-error\/50{border-color:rgb(var(--nx-error)/0.5)}
.border-nexus-muted{--tw-border-opacity:1;border-color:rgb(var(--nx-muted)/var(--tw-border-opacity,1))}
.border-nexus-muted\/50{border-color:rgb(var(--nx-muted)/0.5)}
.border-nexus-mythic{--tw-border-opacity:1;border-color:rgb(var(--nx-mythic)/var(--tw-border-opacity,1))}
.border-nexus-rare{--tw-border-opacity:1;border-color:rgb(var(--nx-rare)/var(--tw-border-opacity,1))}
.border-nexus-success{--tw-border-opacity:1;border-color:rgb(var(--nx-success)/var(--tw-border-opacity,1))}
.border-nexus-success\/30{border-color:rgb(var(--nx-success)/0.3)}
.border-nexus-success\/40{border-color:rgb(var(--nx-success)/0.4)}
.border-nexus-success\/50{border-color:rgb(var(--nx-success)/0.5)}
.border-nexus-surface{--tw-border-opacity:1;border-color:rgb(var(--nx-surface)/var(--tw-border-opacity,1))}
.border-nexus-surface-alt{--tw-border-opacity:1;border-color:rgb(var(--nx-surface-alt)/var(--tw-border-opacity,1))}
.border-nexus-surface-hover{--tw-border-opacity:1;border-color:rgb(var(--nx-surface-hover)/var(--tw-border-opacity,1))}
.border-nexus-surface\/40{border-color:rgb(var(--nx-surface)/0.4)}
.border-nexus-surface\/50{border-color:rgb(var(--nx-surface)/0.5)}
.border-nexus-text{--tw-border-opacity:1;border-color:rgb(var(--nx-text)/var(--tw-border-opacity,1))}
.border-nexus-track{--tw-border-opacity:1;border-color:rgb(var(--nx-track)/var(--tw-border-opacity,1))}
.border-nexus-uncommon{--tw-border-opacity:1;border-color:rgb(var(--nx-uncommon)/var(--tw-border-opacity,1))}
.border-nexus-violet{--tw-border-opacity:1;border-color:rgb(var(--nx-violet)/var(--tw-border-opacity,1))}
.border-nexus-violet\/40{border-color:rgb(var(--nx-violet)/0.4)}
.border-nexus-violet\/50{border-color:rgb(var(--nx-violet)/0.5)}
.border-nexus-warning{--tw-border-opacity:1;border-color:rgb(var(--nx-warning)/var(--tw-border-opacity,1))}
.border-nexus-warning\/30{border-color:rgb(var(--nx-warning)/0.3)}
.border-nexus-warning\/40{border-color:rgb(var(--nx-warning)/0.4)}
.border-nexus-warning\/50{border-color:rgb(var(--nx-warning)/0.5)}
.border-slate-400\/10{border-color:rgb(var(--nx-muted)/0.1)}
.border-slate-700{--tw-border-opacity:1;border-color:rgb(var(--nx-slate-700)/var(--tw-border-opacity,1))}
.border-slate-700\/50{border-color:rgb(var(--nx-slate-700)/0.5)}
.border-slate-800{--tw-border-opacity:1;border-color:rgb(var(--nx-slate-800)/var(--tw-border-opacity,1))}
.border-slate-900{--tw-border-opacity:1;border-color:rgb(var(--nx-card)/var(--tw-border-opacity,1))}
.border-transparent{border-color:#0000}
.border-white\/10{border-color:rgb(var(--nx-hair)/0.1)}
.border-white\/20{border-color:rgb(var(--nx-hair)/0.2)}
.border-white\/5{border-color:rgb(var(--nx-hair)/0.05)}
.border-t-nexus-blue{--tw-border-opacity:1;border-top-color:rgb(var(--nx-accent)/var(--tw-border-opacity,1))}
.border-t-nexus-violet{--tw-border-opacity:1;border-top-color:rgb(var(--nx-violet)/var(--tw-border-opacity,1))}
.bg-amber-500{--tw-bg-opacity:1;background-color:rgb(245 158 11/var(--tw-bg-opacity,1))}
.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}
.bg-brand-discord,.bg-discord{--tw-bg-opacity:1;background-color:rgb(88 101 242/var(--tw-bg-opacity,1))}
.bg-emerald-500{--tw-bg-opacity:1;background-color:rgb(16 185 129/var(--tw-bg-opacity,1))}
.bg-fuchsia-600\/10{background-color:#c026d31a}
.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(var(--nx-slate-800)/var(--tw-bg-opacity,1))}
.bg-mtg-b{--tw-bg-opacity:1;background-color:rgb(var(--nx-mtg-b)/var(--tw-bg-opacity,1))}
.bg-mtg-b\/10{background-color:rgb(var(--nx-mtg-b)/0.1)}
.bg-mtg-b\/20{background-color:rgb(var(--nx-mtg-b)/0.2)}
.bg-mtg-b\/30{background-color:rgb(var(--nx-mtg-b)/0.3)}
.bg-mtg-b\/40{background-color:rgb(var(--nx-mtg-b)/0.4)}
.bg-mtg-b\/50{background-color:rgb(var(--nx-mtg-b)/0.5)}
.bg-mtg-b\/60{background-color:rgb(var(--nx-mtg-b)/0.6)}
.bg-mtg-b\/70{background-color:rgb(var(--nx-mtg-b)/0.7)}
.bg-mtg-b\/80{background-color:rgb(var(--nx-mtg-b)/0.8)}
.bg-mtg-b\/90{background-color:rgb(var(--nx-mtg-b)/0.9)}
.bg-mtg-c{--tw-bg-opacity:1;background-color:rgb(var(--nx-mtg-c)/var(--tw-bg-opacity,1))}
.bg-mtg-c\/10{background-color:rgb(var(--nx-mtg-c)/0.1)}
.bg-mtg-c\/20{background-color:rgb(var(--nx-mtg-c)/.2)}
.bg-mtg-c\/30{background-color:rgb(var(--nx-mtg-c)/0.3)}
.bg-mtg-c\/40{background-color:rgb(var(--nx-mtg-c)/.4)}
.bg-mtg-c\/50{background-color:rgb(var(--nx-mtg-c)/0.5)}
.bg-mtg-c\/60{background-color:rgb(var(--nx-mtg-c)/.6)}
.bg-mtg-c\/70{background-color:rgb(var(--nx-mtg-c)/0.7)}
.bg-mtg-c\/80{background-color:rgb(var(--nx-mtg-c)/.8)}
.bg-mtg-c\/90{background-color:rgb(var(--nx-mtg-c)/0.9)}
.bg-mtg-g{--tw-bg-opacity:1;background-color:rgb(var(--nx-mtg-g)/var(--tw-bg-opacity,1))}
.bg-mtg-g\/10{background-color:rgb(var(--nx-mtg-g)/0.1)}
.bg-mtg-g\/20{background-color:rgb(var(--nx-mtg-g)/0.2)}
.bg-mtg-g\/30{background-color:rgb(var(--nx-mtg-g)/0.3)}
.bg-mtg-g\/40{background-color:rgb(var(--nx-mtg-g)/0.4)}
.bg-mtg-g\/50{background-color:rgb(var(--nx-mtg-g)/0.5)}
.bg-mtg-g\/60{background-color:rgb(var(--nx-mtg-g)/0.6)}
.bg-mtg-g\/70{background-color:rgb(var(--nx-mtg-g)/0.7)}
.bg-mtg-g\/80{background-color:rgb(var(--nx-mtg-g)/0.8)}
.bg-mtg-g\/90{background-color:rgb(var(--nx-mtg-g)/0.9)}
.bg-mtg-r{--tw-bg-opacity:1;background-color:rgb(var(--nx-mtg-r)/var(--tw-bg-opacity,1))}
.bg-mtg-r\/10{background-color:rgb(var(--nx-mtg-r)/0.1)}
.bg-mtg-r\/20{background-color:rgb(var(--nx-mtg-r)/0.2)}
.bg-mtg-r\/30{background-color:rgb(var(--nx-mtg-r)/0.3)}
.bg-mtg-r\/40{background-color:rgb(var(--nx-mtg-r)/0.4)}
.bg-mtg-r\/50{background-color:rgb(var(--nx-mtg-r)/0.5)}
.bg-mtg-r\/60{background-color:rgb(var(--nx-mtg-r)/0.6)}
.bg-mtg-r\/70{background-color:rgb(var(--nx-mtg-r)/0.7)}
.bg-mtg-r\/80{background-color:rgb(var(--nx-mtg-r)/0.8)}
.bg-mtg-r\/90{background-color:rgb(var(--nx-mtg-r)/0.9)}
.bg-mtg-u{--tw-bg-opacity:1;background-color:rgb(var(--nx-mtg-u)/var(--tw-bg-opacity,1))}
.bg-mtg-u\/10{background-color:rgb(var(--nx-mtg-u)/0.1)}
.bg-mtg-u\/20{background-color:rgb(var(--nx-mtg-u)/0.2)}
.bg-mtg-u\/30{background-color:rgb(var(--nx-mtg-u)/0.3)}
.bg-mtg-u\/40{background-color:rgb(var(--nx-mtg-u)/0.4)}
.bg-mtg-u\/50{background-color:rgb(var(--nx-mtg-u)/0.5)}
.bg-mtg-u\/60{background-color:rgb(var(--nx-mtg-u)/0.6)}
.bg-mtg-u\/70{background-color:rgb(var(--nx-mtg-u)/0.7)}
.bg-mtg-u\/80{background-color:rgb(var(--nx-mtg-u)/0.8)}
.bg-mtg-u\/90{background-color:rgb(var(--nx-mtg-u)/0.9)}
.bg-mtg-w{--tw-bg-opacity:1;background-color:rgb(var(--nx-mtg-w)/var(--tw-bg-opacity,1))}
.bg-mtg-w\/10{background-color:rgb(var(--nx-mtg-w)/0.1)}
.bg-mtg-w\/20{background-color:rgb(var(--nx-mtg-w)/0.2)}
.bg-mtg-w\/30{background-color:rgb(var(--nx-mtg-w)/0.3)}
.bg-mtg-w\/40{background-color:rgb(var(--nx-mtg-w)/0.4)}
.bg-mtg-w\/50{background-color:rgb(var(--nx-mtg-w)/0.5)}
.bg-mtg-w\/60{background-color:rgb(var(--nx-mtg-w)/0.6)}
.bg-mtg-w\/70{background-color:rgb(var(--nx-mtg-w)/0.7)}
.bg-mtg-w\/80{background-color:rgb(var(--nx-mtg-w)/0.8)}
.bg-mtg-w\/90{background-color:rgb(var(--nx-mtg-w)/0.9)}
.bg-nexus-base{--tw-bg-opacity:1;background-color:rgb(var(--nx-base)/var(--tw-bg-opacity,1))}
.bg-nexus-base\/20{background-color:rgb(var(--nx-base)/0.2)}
.bg-nexus-base\/40{background-color:rgb(var(--nx-base)/0.4)}
.bg-nexus-base\/50{background-color:rgb(var(--nx-base)/0.5)}
.bg-nexus-base\/60{background-color:rgb(var(--nx-base)/0.6)}
.bg-nexus-base\/70{background-color:rgb(var(--nx-base)/0.7)}
.bg-nexus-base\/80{background-color:rgb(var(--nx-base)/0.8)}
.bg-nexus-base\/90{background-color:rgb(var(--nx-base)/0.9)}
.bg-nexus-base\/95{background-color:rgb(var(--nx-base)/0.95)}
.bg-nexus-blue{--tw-bg-opacity:1;background-color:rgb(var(--nx-accent)/var(--tw-bg-opacity,1))}
.bg-nexus-blue\/10{background-color:rgb(var(--nx-accent)/0.1)}
.bg-nexus-blue\/20{background-color:rgb(var(--nx-accent)/0.2)}
.bg-nexus-blue\/30{background-color:rgb(var(--nx-accent)/0.3)}
.bg-nexus-blue\/5{background-color:rgb(var(--nx-accent)/0.05)}
.bg-nexus-blue\/90{background-color:rgb(var(--nx-accent)/0.9)}
.bg-nexus-border{--tw-bg-opacity:1;background-color:rgb(var(--nx-surface-hover)/var(--tw-bg-opacity,1))}
.bg-nexus-card{--tw-bg-opacity:1;background-color:rgb(var(--nx-card)/var(--tw-bg-opacity,1))}
.bg-nexus-common{--tw-bg-opacity:1;background-color:rgb(var(--nx-muted)/var(--tw-bg-opacity,1))}
.bg-nexus-dark{--tw-bg-opacity:1;background-color:rgb(var(--nx-dark)/var(--tw-bg-opacity,1))}
.bg-nexus-error{--tw-bg-opacity:1;background-color:rgb(var(--nx-error)/var(--tw-bg-opacity,1))}
.bg-nexus-error\/10{background-color:rgb(var(--nx-error)/0.1)}
.bg-nexus-error\/20{background-color:rgb(var(--nx-error)/0.2)}
.bg-nexus-error\/5{background-color:rgb(var(--nx-error)/0.05)}
.bg-nexus-error\/90{background-color:rgb(var(--nx-error)/0.9)}
.bg-nexus-muted{--tw-bg-opacity:1;background-color:rgb(var(--nx-muted)/var(--tw-bg-opacity,1))}
.bg-nexus-mythic{--tw-bg-opacity:1;background-color:rgb(var(--nx-mythic)/var(--tw-bg-opacity,1))}
.bg-nexus-rare{--tw-bg-opacity:1;background-color:rgb(var(--nx-rare)/var(--tw-bg-opacity,1))}
.bg-nexus-success{--tw-bg-opacity:1;background-color:rgb(var(--nx-success)/var(--tw-bg-opacity,1))}
.bg-nexus-success\/10{background-color:rgb(var(--nx-success)/0.1)}
.bg-nexus-success\/20{background-color:rgb(var(--nx-success)/0.2)}
.bg-nexus-success\/90{background-color:rgb(var(--nx-success)/0.9)}
.bg-nexus-surface{--tw-bg-opacity:1;background-color:rgb(var(--nx-surface)/var(--tw-bg-opacity,1))}
.bg-nexus-surface-alt{--tw-bg-opacity:1;background-color:rgb(var(--nx-surface-alt)/var(--tw-bg-opacity,1))}
.bg-nexus-surface-hover{--tw-bg-opacity:1;background-color:rgb(var(--nx-surface-hover)/var(--tw-bg-opacity,1))}
.bg-nexus-surface-hover\/90{background-color:rgb(var(--nx-surface-hover)/0.9)}
.bg-nexus-surface\/20{background-color:rgb(var(--nx-surface)/0.2)}
.bg-nexus-surface\/30{background-color:rgb(var(--nx-surface)/0.3)}
.bg-nexus-surface\/40{background-color:rgb(var(--nx-surface)/0.4)}
.bg-nexus-surface\/50{background-color:rgb(var(--nx-surface)/0.5)}
.bg-nexus-surface\/60{background-color:rgb(var(--nx-surface)/0.6)}
.bg-nexus-surface\/80{background-color:rgb(var(--nx-surface)/0.8)}
.bg-nexus-surface\/90{background-color:rgb(var(--nx-surface)/0.9)}
.bg-nexus-text{--tw-bg-opacity:1;background-color:rgb(var(--nx-text)/var(--tw-bg-opacity,1))}
.bg-nexus-track{--tw-bg-opacity:1;background-color:rgb(var(--nx-track)/var(--tw-bg-opacity,1))}
.bg-nexus-uncommon{--tw-bg-opacity:1;background-color:rgb(var(--nx-uncommon)/var(--tw-bg-opacity,1))}
.bg-nexus-violet{--tw-bg-opacity:1;background-color:rgb(var(--nx-violet)/var(--tw-bg-opacity,1))}
.bg-nexus-violet\/10{background-color:rgb(var(--nx-violet)/0.1)}
.bg-nexus-violet\/20{background-color:rgb(var(--nx-violet)/0.2)}
.bg-nexus-violet\/30{background-color:rgb(var(--nx-violet)/0.3)}
.bg-nexus-violet\/80{background-color:rgb(var(--nx-violet)/0.8)}
.bg-nexus-violet\/90{background-color:rgb(var(--nx-violet)/0.9)}
.bg-nexus-warning{--tw-bg-opacity:1;background-color:rgb(var(--nx-warning)/var(--tw-bg-opacity,1))}
.bg-nexus-warning\/10{background-color:rgb(var(--nx-warning)/0.1)}
.bg-nexus-warning\/20{background-color:rgb(var(--nx-warning)/0.2)}
.bg-nexus-warning\/5{background-color:rgb(var(--nx-warning)/0.05)}
.bg-nexus-warning\/50{background-color:rgb(var(--nx-warning)/0.5)}
.bg-nexus-warning\/90{background-color:rgb(var(--nx-warning)/0.9)}
.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(var(--nx-slate-100)/var(--tw-bg-opacity,1))}
.bg-slate-400{--tw-bg-opacity:1;background-color:rgb(var(--nx-muted)/var(--tw-bg-opacity,1))}
.bg-slate-700{--tw-bg-opacity:1;background-color:rgb(var(--nx-slate-700)/var(--tw-bg-opacity,1))}
.bg-slate-800{--tw-bg-opacity:1;background-color:rgb(var(--nx-slate-800)/var(--tw-bg-opacity,1))}
.bg-slate-800\/60{background-color:rgb(var(--nx-slate-800)/0.6)}
.bg-slate-900{--tw-bg-opacity:1;background-color:rgb(var(--nx-card)/var(--tw-bg-opacity,1))}
.bg-slate-900\/40{background-color:rgb(var(--nx-card)/0.4)}
.bg-slate-900\/80{background-color:rgb(var(--nx-card)/0.8)}
.bg-slate-900\/95{background-color:rgb(var(--nx-card)/0.95)}
.bg-slate-950{--tw-bg-opacity:1;background-color:rgb(var(--nx-dark)/var(--tw-bg-opacity,1))}
.bg-transparent{background-color:initial}
.bg-violet-600\/20{background-color:rgb(var(--nx-violet)/0.2)}
.bg-white\/5{background-color:rgb(var(--nx-hair)/0.05)}
.bg-\[url\(\'\$\{imgA\}\'\)\]{background-image:url("${imgA}")}
.bg-\[url\(\'\$\{imgB\}\'\)\]{background-image:url("${imgB}")}
.bg-\[url\(\'\$\{img\}\'\)\]{background-image:url("${img}")}
.bg-\[url\(\'\$\{targetImage\}\'\)\]{background-image:url("${targetImage}")}
.bg-\[url\(\'https\:\/\/www\.transparenttextures\.com\/patterns\/stardust\.png\'\)\]{background-image:url(https://www.transparenttextures.com/patterns/stardust.png)}
.bg-\[url\(\.\.\.\)\]{background-image:url(...)}
.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}
.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}
.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}
.bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}
.from-black{--tw-gradient-from:#000 var(--tw-gradient-from-position);--tw-gradient-to:#0000 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-discord\/20{--tw-gradient-from:#5865f233 var(--tw-gradient-from-position);--tw-gradient-to:#5865f200 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-indigo-900\/40{--tw-gradient-from:#312e8166 var(--tw-gradient-from-position);--tw-gradient-to:#312e8100 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-indigo-950\/30{--tw-gradient-from:#1e1b4b4d var(--tw-gradient-from-position);--tw-gradient-to:#1e1b4b00 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-kofi\/20{--tw-gradient-from:#ff5e5b33 var(--tw-gradient-from-position);--tw-gradient-to:#ff5e5b00 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-mtg-b{--tw-gradient-from:rgb(var(--nx-mtg-b)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-mtg-b)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-mtg-c{--tw-gradient-from:rgb(var(--nx-mtg-c)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-mtg-c)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-mtg-g{--tw-gradient-from:rgb(var(--nx-mtg-g)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-mtg-g)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-mtg-r{--tw-gradient-from:rgb(var(--nx-mtg-r)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-mtg-r)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-mtg-u{--tw-gradient-from:rgb(var(--nx-mtg-u)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-mtg-u)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-mtg-w{--tw-gradient-from:rgb(var(--nx-mtg-w)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-mtg-w)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-nexus-base{--tw-gradient-from:rgb(var(--nx-base)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-base)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-nexus-blue{--tw-gradient-from:rgb(var(--nx-accent)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-accent)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-nexus-violet{--tw-gradient-from:rgb(var(--nx-violet)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-violet)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-teal-500\/30{--tw-gradient-from:#14b8a64d var(--tw-gradient-from-position);--tw-gradient-to:#14b8a600 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-violet-400{--tw-gradient-from:rgb(var(--nx-violet-lit)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-violet-lit)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-violet-500{--tw-gradient-from:#8b5cf6 var(--tw-gradient-from-position);--tw-gradient-to:#8b5cf600 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-violet-600{--tw-gradient-from:rgb(var(--nx-violet)) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-violet)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-violet-900\/40{--tw-gradient-from:#4c1d9566 var(--tw-gradient-from-position);--tw-gradient-to:#4c1d9500 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.from-white\/5{--tw-gradient-from:rgb(var(--nx-hair)/0.05) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--nx-hair)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.via-black\/80{--tw-gradient-to:#0000 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),#000c var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-fuchsia-400{--tw-gradient-to:#e879f900 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),#e879f9 var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-mtg-b{--tw-gradient-to:rgb(var(--nx-mtg-b)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--nx-mtg-b)) var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-mtg-c{--tw-gradient-to:rgb(var(--nx-mtg-c)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--nx-mtg-c)) var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-mtg-g{--tw-gradient-to:rgb(var(--nx-mtg-g)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--nx-mtg-g)) var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-mtg-r{--tw-gradient-to:rgb(var(--nx-mtg-r)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--nx-mtg-r)) var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-mtg-u{--tw-gradient-to:rgb(var(--nx-mtg-u)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--nx-mtg-u)) var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-mtg-w{--tw-gradient-to:rgb(var(--nx-mtg-w)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--nx-mtg-w)) var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-nexus-base\/40{--tw-gradient-to:rgb(var(--nx-base)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--nx-base)/0.4) var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-nexus-base\/60{--tw-gradient-to:rgb(var(--nx-base)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--nx-base)/0.6) var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-nexus-base\/80{--tw-gradient-to:rgb(var(--nx-base)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--nx-base)/0.8) var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-slate-950{--tw-gradient-to:rgb(var(--nx-dark)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--nx-dark)) var(--tw-gradient-via-position),var(--tw-gradient-to)}
.via-transparent{--tw-gradient-to:#0000 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),#0000 var(--tw-gradient-via-position),var(--tw-gradient-to)}
.to-cyan-500{--tw-gradient-to:#06b6d4 var(--tw-gradient-to-position)}
.to-fuchsia-400{--tw-gradient-to:#e879f9 var(--tw-gradient-to-position)}
.to-fuchsia-600{--tw-gradient-to:#c026d3 var(--tw-gradient-to-position)}
.to-indigo-400{--tw-gradient-to:#818cf8 var(--tw-gradient-to-position)}
.to-mtg-b{--tw-gradient-to:rgb(var(--nx-mtg-b)) var(--tw-gradient-to-position)}
.to-mtg-c{--tw-gradient-to:rgb(var(--nx-mtg-c)) var(--tw-gradient-to-position)}
.to-mtg-g{--tw-gradient-to:rgb(var(--nx-mtg-g)) var(--tw-gradient-to-position)}
.to-mtg-r{--tw-gradient-to:rgb(var(--nx-mtg-r)) var(--tw-gradient-to-position)}
.to-mtg-u{--tw-gradient-to:rgb(var(--nx-mtg-u)) var(--tw-gradient-to-position)}
.to-mtg-w{--tw-gradient-to:rgb(var(--nx-mtg-w)) var(--tw-gradient-to-position)}
.to-nexus-base{--tw-gradient-to:rgb(var(--nx-base)) var(--tw-gradient-to-position)}
.to-nexus-violet{--tw-gradient-to:rgb(var(--nx-violet)) var(--tw-gradient-to-position)}
.to-slate-900\/60{--tw-gradient-to:rgb(var(--nx-card)/0.6) var(--tw-gradient-to-position)}
.to-slate-950{--tw-gradient-to:rgb(var(--nx-dark)) var(--tw-gradient-to-position)}
.to-transparent{--tw-gradient-to:#0000 var(--tw-gradient-to-position)}
.bg-cover{background-size:cover}
.bg-clip-text{-webkit-background-clip:text;background-clip:text}
.bg-center{background-position:50%}
.fill-current{fill:currentColor}
.fill-mtg-b{fill:rgb(var(--nx-mtg-b))}
.fill-mtg-c{fill:#ccc}
.fill-mtg-g{fill:rgb(var(--nx-mtg-g))}
.fill-mtg-r{fill:rgb(var(--nx-mtg-r))}
.fill-mtg-u{fill:rgb(var(--nx-mtg-u))}
.fill-mtg-w{fill:rgb(var(--nx-mtg-w))}
.stroke-mtg-b{stroke:rgb(var(--nx-mtg-b))}
.stroke-mtg-c{stroke:#ccc}
.stroke-mtg-g{stroke:rgb(var(--nx-mtg-g))}
.stroke-mtg-r{stroke:rgb(var(--nx-mtg-r))}
.stroke-mtg-u{stroke:rgb(var(--nx-mtg-u))}
.stroke-mtg-w{stroke:rgb(var(--nx-mtg-w))}
.stroke-nexus-blue{stroke:rgb(var(--nx-accent))}
.stroke-nexus-error{stroke:rgb(var(--nx-error))}
.stroke-nexus-success{stroke:rgb(var(--nx-success))}
.stroke-nexus-violet{stroke:rgb(var(--nx-violet))}
.stroke-slate-800\/40{stroke:rgb(var(--nx-slate-800)/0.4)}
.object-cover{-o-object-fit:cover;object-fit:cover}
.object-center{-o-object-position:center;object-position:center}
.object-top{-o-object-position:top;object-position:top}
.p-0{padding:0}
.p-1{padding:.25rem}
.p-10{padding:2.5rem}
.p-2{padding:.5rem}
.p-3{padding:.75rem}
.p-4{padding:1rem}
.p-5{padding:1.25rem}
.p-6{padding:1.5rem}
.p-8{padding:2rem}
.p-\[1px\]{padding:1px}
.px-0\.5{padding-left:.125rem;padding-right:.125rem}
.px-1{padding-left:.25rem;padding-right:.25rem}
.px-1\.5{padding-left:.375rem;padding-right:.375rem}
.px-2{padding-left:.5rem;padding-right:.5rem}
.px-2\.5{padding-left:.625rem;padding-right:.625rem}
.px-3{padding-left:.75rem;padding-right:.75rem}
.px-3\.5{padding-left:.875rem;padding-right:.875rem}
.px-4{padding-left:1rem;padding-right:1rem}
.px-5{padding-left:1.25rem;padding-right:1.25rem}
.px-6{padding-left:1.5rem;padding-right:1.5rem}
.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}
.py-1{padding-top:.25rem;padding-bottom:.25rem}
.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}
.py-12{padding-top:3rem;padding-bottom:3rem}
.py-2{padding-top:.5rem;padding-bottom:.5rem}
.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}
.py-20{padding-top:5rem;padding-bottom:5rem}
.py-3{padding-top:.75rem;padding-bottom:.75rem}
.py-3\.5{padding-top:.875rem;padding-bottom:.875rem}
.py-32{padding-top:8rem;padding-bottom:8rem}
.py-4{padding-top:1rem;padding-bottom:1rem}
.py-6{padding-top:1.5rem;padding-bottom:1.5rem}
.py-8{padding-top:2rem;padding-bottom:2rem}
.py-\[1px\]{padding-top:1px;padding-bottom:1px}
.py-\[3px\]{padding-top:3px;padding-bottom:3px}
.pb-0\.5{padding-bottom:.125rem}
.pb-1{padding-bottom:.25rem}
.pb-10{padding-bottom:2.5rem}
.pb-16{padding-bottom:4rem}
.pb-2{padding-bottom:.5rem}
.pb-20{padding-bottom:5rem}
.pb-24{padding-bottom:6rem}
.pb-3{padding-bottom:.75rem}
.pb-4{padding-bottom:1rem}
.pb-40{padding-bottom:10rem}
.pb-6{padding-bottom:1.5rem}
.pl-1{padding-left:.25rem}
.pl-1\.5{padding-left:.375rem}
.pl-10{padding-left:2.5rem}
.pl-11{padding-left:2.75rem}
.pl-9{padding-left:2.25rem}
.pr-1{padding-right:.25rem}
.pr-3{padding-right:.75rem}
.pr-4{padding-right:1rem}
.pr-8{padding-right:2rem}
.pt-0\.5{padding-top:.125rem}
.pt-10{padding-top:2.5rem}
.pt-12{padding-top:3rem}
.pt-2{padding-top:.5rem}
.pt-4{padding-top:1rem}
.pt-5{padding-top:1.25rem}
.pt-6{padding-top:1.5rem}
.pt-8{padding-top:2rem}
.text-left{text-align:left}
.text-center{text-align:center}
.text-right{text-align:right}
.font-display{font-family:Outfit,ui-sans-serif,system-ui,sans-serif}
.font-mono{font-family:Fira Code,ui-monospace,SFMono-Regular,monospace}
.font-sans{font-family:Inter,ui-sans-serif,system-ui,-apple-system,sans-serif}
.text-2xl{font-size:1.5rem;line-height:2rem}
.text-3xl{font-size:1.875rem;line-height:2.25rem}
.text-4xl{font-size:2.25rem;line-height:2.5rem}
.text-5xl{font-size:3rem;line-height:1}
.text-\[10px\]{font-size:10px}
.text-\[11px\]{font-size:11px}
.text-\[12px\]{font-size:12px}
.text-\[13px\]{font-size:13px}
.text-\[14px\]{font-size:14px}
.text-\[22px\]{font-size:22px}
.text-\[8px\]{font-size:8px}
.text-\[9px\]{font-size:9px}
.text-base{font-size:1rem;line-height:1.5rem}
.text-lg{font-size:1.125rem;line-height:1.75rem}
.text-nexus-tiny{font-size:.625rem;line-height:.75rem;letter-spacing:.05em}
.text-sm{font-size:.875rem;line-height:1.25rem}
.text-xl{font-size:1.25rem;line-height:1.75rem}
.text-xs{font-size:.75rem;line-height:1rem}
.font-black{font-weight:900}
.font-bold{font-weight:700}
.font-extrabold{font-weight:800}
.font-medium{font-weight:500}
.font-normal{font-weight:400}
.font-semibold{font-weight:600}
.uppercase{text-transform:uppercase}
.normal-case{text-transform:none}
.italic{font-style:italic}
.leading-4{line-height:1rem}
.leading-\[1\.1\]{line-height:1.1}
.leading-none{line-height:1}
.leading-relaxed{line-height:1.625}
.leading-tight{line-height:1.25}
.tracking-\[0\.2em\]{letter-spacing:.2em}
.tracking-normal{letter-spacing:0}
.tracking-tight{letter-spacing:-.025em}
.tracking-wide{letter-spacing:.025em}
.tracking-wider{letter-spacing:.05em}
.tracking-widest{letter-spacing:.1em}
.text-amber-400{--tw-text-opacity:1;color:rgb(var(--nx-rare)/var(--tw-text-opacity,1))}
.text-brand-google-blue{--tw-text-opacity:1;color:rgb(66 133 244/var(--tw-text-opacity,1))}
.text-brand-google-green{--tw-text-opacity:1;color:rgb(52 168 83/var(--tw-text-opacity,1))}
.text-brand-google-red{--tw-text-opacity:1;color:rgb(234 67 53/var(--tw-text-opacity,1))}
.text-brand-google-yellow{--tw-text-opacity:1;color:rgb(251 188 5/var(--tw-text-opacity,1))}
.text-brand-twitch{--tw-text-opacity:1;color:rgb(145 70 255/var(--tw-text-opacity,1))}
.text-discord{--tw-text-opacity:1;color:rgb(88 101 242/var(--tw-text-opacity,1))}
.text-emerald-400{--tw-text-opacity:1;color:rgb(var(--nx-success-lit)/var(--tw-text-opacity,1))}
.text-fuchsia-400{--tw-text-opacity:1;color:rgb(232 121 249/var(--tw-text-opacity,1))}
.text-indigo-400{--tw-text-opacity:1;color:rgb(129 140 248/var(--tw-text-opacity,1))}
.text-kofi{--tw-text-opacity:1;color:rgb(255 94 91/var(--tw-text-opacity,1))}
.text-mtg-b{--tw-text-opacity:1;color:rgb(var(--nx-mtg-b)/var(--tw-text-opacity,1))}
.text-mtg-b\/10{color:rgb(var(--nx-mtg-b)/0.1)}
.text-mtg-b\/20{color:rgb(var(--nx-mtg-b)/0.2)}
.text-mtg-b\/30{color:rgb(var(--nx-mtg-b)/0.3)}
.text-mtg-b\/40{color:rgb(var(--nx-mtg-b)/0.4)}
.text-mtg-b\/50{color:rgb(var(--nx-mtg-b)/0.5)}
.text-mtg-b\/60{color:rgb(var(--nx-mtg-b)/0.6)}
.text-mtg-b\/70{color:rgb(var(--nx-mtg-b)/0.7)}
.text-mtg-b\/80{color:rgb(var(--nx-mtg-b)/0.8)}
.text-mtg-b\/90{color:rgb(var(--nx-mtg-b)/0.9)}
.text-mtg-c{--tw-text-opacity:1;color:rgb(var(--nx-mtg-c)/var(--tw-text-opacity,1))}
.text-mtg-c\/10{color:rgb(var(--nx-mtg-c)/0.1)}
.text-mtg-c\/20{color:rgb(var(--nx-mtg-c)/.2)}
.text-mtg-c\/30{color:rgb(var(--nx-mtg-c)/0.3)}
.text-mtg-c\/40{color:rgb(var(--nx-mtg-c)/.4)}
.text-mtg-c\/50{color:rgb(var(--nx-mtg-c)/0.5)}
.text-mtg-c\/60{color:rgb(var(--nx-mtg-c)/.6)}
.text-mtg-c\/70{color:rgb(var(--nx-mtg-c)/0.7)}
.text-mtg-c\/80{color:rgb(var(--nx-mtg-c)/.8)}
.text-mtg-c\/90{color:rgb(var(--nx-mtg-c)/0.9)}
.text-mtg-g{--tw-text-opacity:1;color:rgb(var(--nx-mtg-g)/var(--tw-text-opacity,1))}
.text-mtg-g\/10{color:rgb(var(--nx-mtg-g)/0.1)}
.text-mtg-g\/20{color:rgb(var(--nx-mtg-g)/0.2)}
.text-mtg-g\/30{color:rgb(var(--nx-mtg-g)/0.3)}
.text-mtg-g\/40{color:rgb(var(--nx-mtg-g)/0.4)}
.text-mtg-g\/50{color:rgb(var(--nx-mtg-g)/0.5)}
.text-mtg-g\/60{color:rgb(var(--nx-mtg-g)/0.6)}
.text-mtg-g\/70{color:rgb(var(--nx-mtg-g)/0.7)}
.text-mtg-g\/80{color:rgb(var(--nx-mtg-g)/0.8)}
.text-mtg-g\/90{color:rgb(var(--nx-mtg-g)/0.9)}
.text-mtg-r{--tw-text-opacity:1;color:rgb(var(--nx-mtg-r)/var(--tw-text-opacity,1))}
.text-mtg-r\/10{color:rgb(var(--nx-mtg-r)/0.1)}
.text-mtg-r\/20{color:rgb(var(--nx-mtg-r)/0.2)}
.text-mtg-r\/30{color:rgb(var(--nx-mtg-r)/0.3)}
.text-mtg-r\/40{color:rgb(var(--nx-mtg-r)/0.4)}
.text-mtg-r\/50{color:rgb(var(--nx-mtg-r)/0.5)}
.text-mtg-r\/60{color:rgb(var(--nx-mtg-r)/0.6)}
.text-mtg-r\/70{color:rgb(var(--nx-mtg-r)/0.7)}
.text-mtg-r\/80{color:rgb(var(--nx-mtg-r)/0.8)}
.text-mtg-r\/90{color:rgb(var(--nx-mtg-r)/0.9)}
.text-mtg-u{--tw-text-opacity:1;color:rgb(var(--nx-mtg-u)/var(--tw-text-opacity,1))}
.text-mtg-u\/10{color:rgb(var(--nx-mtg-u)/0.1)}
.text-mtg-u\/20{color:rgb(var(--nx-mtg-u)/0.2)}
.text-mtg-u\/30{color:rgb(var(--nx-mtg-u)/0.3)}
.text-mtg-u\/40{color:rgb(var(--nx-mtg-u)/0.4)}
.text-mtg-u\/50{color:rgb(var(--nx-mtg-u)/0.5)}
.text-mtg-u\/60{color:rgb(var(--nx-mtg-u)/0.6)}
.text-mtg-u\/70{color:rgb(var(--nx-mtg-u)/0.7)}
.text-mtg-u\/80{color:rgb(var(--nx-mtg-u)/0.8)}
.text-mtg-u\/90{color:rgb(var(--nx-mtg-u)/0.9)}
.text-mtg-w{--tw-text-opacity:1;color:rgb(var(--nx-mtg-w)/var(--tw-text-opacity,1))}
.text-mtg-w\/10{color:rgb(var(--nx-mtg-w)/0.1)}
.text-mtg-w\/20{color:rgb(var(--nx-mtg-w)/0.2)}
.text-mtg-w\/30{color:rgb(var(--nx-mtg-w)/0.3)}
.text-mtg-w\/40{color:rgb(var(--nx-mtg-w)/0.4)}
.text-mtg-w\/50{color:rgb(var(--nx-mtg-w)/0.5)}
.text-mtg-w\/60{color:rgb(var(--nx-mtg-w)/0.6)}
.text-mtg-w\/70{color:rgb(var(--nx-mtg-w)/0.7)}
.text-mtg-w\/80{color:rgb(var(--nx-mtg-w)/0.8)}
.text-mtg-w\/90{color:rgb(var(--nx-mtg-w)/0.9)}
.text-nexus-base{--tw-text-opacity:1;color:rgb(var(--nx-base)/var(--tw-text-opacity,1))}
.text-nexus-blue{--tw-text-opacity:1;color:rgb(var(--nx-accent)/var(--tw-text-opacity,1))}
.text-nexus-blue\/60{color:rgb(var(--nx-accent)/0.6)}
.text-nexus-border{--tw-text-opacity:1;color:rgb(var(--nx-surface-hover)/var(--tw-text-opacity,1))}
.text-nexus-card{--tw-text-opacity:1;color:rgb(var(--nx-card)/var(--tw-text-opacity,1))}
.text-nexus-common{--tw-text-opacity:1;color:rgb(var(--nx-muted)/var(--tw-text-opacity,1))}
.text-nexus-dark{--tw-text-opacity:1;color:rgb(var(--nx-dark)/var(--tw-text-opacity,1))}
.text-nexus-error{--tw-text-opacity:1;color:rgb(var(--nx-error)/var(--tw-text-opacity,1))}
.text-nexus-muted{--tw-text-opacity:1;color:rgb(var(--nx-muted)/var(--tw-text-opacity,1))}
.text-nexus-mythic{--tw-text-opacity:1;color:rgb(var(--nx-mythic)/var(--tw-text-opacity,1))}
.text-nexus-rare{--tw-text-opacity:1;color:rgb(var(--nx-rare)/var(--tw-text-opacity,1))}
.text-nexus-success{--tw-text-opacity:1;color:rgb(var(--nx-success)/var(--tw-text-opacity,1))}
.text-nexus-surface{--tw-text-opacity:1;color:rgb(var(--nx-surface)/var(--tw-text-opacity,1))}
.text-nexus-surface-alt{--tw-text-opacity:1;color:rgb(var(--nx-surface-alt)/var(--tw-text-opacity,1))}
.text-nexus-surface-hover{--tw-text-opacity:1;color:rgb(var(--nx-surface-hover)/var(--tw-text-opacity,1))}
.text-nexus-text{--tw-text-opacity:1;color:rgb(var(--nx-text)/var(--tw-text-opacity,1))}
.text-nexus-track{--tw-text-opacity:1;color:rgb(var(--nx-track)/var(--tw-text-opacity,1))}
.text-nexus-uncommon{--tw-text-opacity:1;color:rgb(var(--nx-uncommon)/var(--tw-text-opacity,1))}
.text-nexus-violet{--tw-text-opacity:1;color:rgb(var(--nx-violet)/var(--tw-text-opacity,1))}
.text-nexus-warning{--tw-text-opacity:1;color:rgb(var(--nx-warning)/var(--tw-text-opacity,1))}
.text-slate-100{--tw-text-opacity:1;color:rgb(var(--nx-slate-100)/var(--tw-text-opacity,1))}
.text-slate-200{--tw-text-opacity:1;color:rgb(var(--nx-slate-200)/var(--tw-text-opacity,1))}
.text-slate-300{--tw-text-opacity:1;color:rgb(var(--nx-slate-300)/var(--tw-text-opacity,1))}
.text-slate-400{--tw-text-opacity:1;color:rgb(var(--nx-muted)/var(--tw-text-opacity,1))}
.text-slate-500{--tw-text-opacity:1;color:rgb(var(--nx-slate-500)/var(--tw-text-opacity,1))}
.text-slate-600{--tw-text-opacity:1;color:rgb(var(--nx-slate-600)/var(--tw-text-opacity,1))}
.text-slate-700{--tw-text-opacity:1;color:rgb(var(--nx-slate-700)/var(--tw-text-opacity,1))}
.text-slate-900{--tw-text-opacity:1;color:rgb(var(--nx-card)/var(--tw-text-opacity,1))}
.text-transparent{color:#0000}
.text-violet-200{--tw-text-opacity:1;color:rgb(221 214 254/var(--tw-text-opacity,1))}
.text-violet-400{--tw-text-opacity:1;color:rgb(var(--nx-violet-lit)/var(--tw-text-opacity,1))}
.text-white{--tw-text-opacity:1;color:rgb(var(--nx-ink)/var(--tw-text-opacity,1))}
.text-white\/70{color:rgb(var(--nx-ink)/0.7)}
.underline{text-decoration-line:underline}
.line-through{text-decoration-line:line-through}
.decoration-nexus-error{text-decoration-color:rgb(var(--nx-error))}
.decoration-transparent{text-decoration-color:#0000}
.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
.placeholder-nexus-muted::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(var(--nx-muted)/var(--tw-placeholder-opacity,1))}
.placeholder-nexus-muted::placeholder{--tw-placeholder-opacity:1;color:rgb(var(--nx-muted)/var(--tw-placeholder-opacity,1))}
.accent-nexus-blue{accent-color:rgb(var(--nx-accent))}
.opacity-0{opacity:0}
.opacity-100{opacity:1}
.opacity-20{opacity:.2}
.opacity-25{opacity:.25}
.opacity-30{opacity:.3}
.opacity-40{opacity:.4}
.opacity-50{opacity:.5}
.opacity-60{opacity:.6}
.opacity-70{opacity:.7}
.opacity-80{opacity:.8}
.opacity-90{opacity:.9}
.opacity-95{opacity:.95}
.opacity-\[0\.05\]{opacity:.05}
.mix-blend-screen{mix-blend-mode:screen}
.mix-blend-difference{mix-blend-mode:difference}
.shadow-2xl{--tw-shadow:0 25px 50px -12px #00000040;--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color)}
.shadow-2xl,.shadow-\[0_0_10px_rgba\(0\2c 225\2c 255\2c 0\.6\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_10px_rgba\(0\2c 225\2c 255\2c 0\.6\)\]{--tw-shadow:0 0 10px rgb(var(--nx-accent)/0.6);--tw-shadow-colored:0 0 10px var(--tw-shadow-color)}
.shadow-\[0_0_15px_rgba\(0\2c 225\2c 255\2c 0\.2\)\]{--tw-shadow:0 0 15px rgb(var(--nx-accent)/0.2);--tw-shadow-colored:0 0 15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_15px_rgba\(0\2c 225\2c 255\2c 0\.4\)\]{--tw-shadow:0 0 15px rgb(var(--nx-accent)/0.4);--tw-shadow-colored:0 0 15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_15px_rgba\(0\2c 225\2c 255\2c 0\.5\)\]{--tw-shadow:0 0 15px rgb(var(--nx-accent)/0.5);--tw-shadow-colored:0 0 15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_15px_rgba\(0\2c 225\2c 255\2c 0\.6\)\]{--tw-shadow:0 0 15px rgb(var(--nx-accent)/0.6);--tw-shadow-colored:0 0 15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_15px_rgba\(139\2c 92\2c 246\2c 0\.4\)\]{--tw-shadow:0 0 15px #8b5cf666;--tw-shadow-colored:0 0 15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_15px_rgba\(245\2c 158\2c 11\2c 0\.5\)\]{--tw-shadow:0 0 15px #f59e0b80;--tw-shadow-colored:0 0 15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_15px_rgba\(5\2c 150\2c 105\2c 0\.2\)\]{--tw-shadow:0 0 15px rgb(var(--nx-success)/0.2);--tw-shadow-colored:0 0 15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_15px_rgba\(88\2c 101\2c 242\2c 0\.25\)\]{--tw-shadow:0 0 15px #5865f240;--tw-shadow-colored:0 0 15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_20px_\$\{color\.glow\}\]{--tw-shadow:0 0 20px ${color.glow};--tw-shadow-colored:0 0 20px var(--tw-shadow-color)}
.shadow-\[0_0_20px_\$\{color\.glow\}\],.shadow-\[0_0_20px_rgba\(0\2c 225\2c 255\2c 0\.6\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_20px_rgba\(0\2c 225\2c 255\2c 0\.6\)\]{--tw-shadow:0 0 20px rgb(var(--nx-accent)/0.6);--tw-shadow-colored:0 0 20px var(--tw-shadow-color)}
.shadow-\[0_0_20px_rgba\(139\2c 92\2c 246\2c 0\.3\)\]{--tw-shadow:0 0 20px #8b5cf64d;--tw-shadow-colored:0 0 20px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_20px_rgba\(139\2c 92\2c 246\2c 0\.4\)\]{--tw-shadow:0 0 20px #8b5cf666;--tw-shadow-colored:0 0 20px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_30px_rgba\(0\2c 0\2c 0\2c 0\.5\)\]{--tw-shadow:0 0 30px #00000080;--tw-shadow-colored:0 0 30px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_40px_rgba\(139\2c 92\2c 246\2c 0\.25\)\]{--tw-shadow:0 0 40px #8b5cf640;--tw-shadow-colored:0 0 40px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_40px_rgba\(225\2c 29\2c 72\2c 0\.8\)\]{--tw-shadow:0 0 40px rgb(var(--nx-error)/0.8);--tw-shadow-colored:0 0 40px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_4px_\#a69f9d\]{--tw-shadow:0 0 4px rgb(var(--nx-mtg-b));--tw-shadow-colored:0 0 4px var(--tw-shadow-color)}
.shadow-\[0_0_4px_\#a69f9d\],.shadow-\[0_0_4px_\#b3ceea\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_4px_\#b3ceea\]{--tw-shadow:0 0 4px rgb(var(--nx-mtg-u));--tw-shadow-colored:0 0 4px var(--tw-shadow-color)}
.shadow-\[0_0_4px_\#c4d3ca\]{--tw-shadow:0 0 4px rgb(var(--nx-mtg-g));--tw-shadow-colored:0 0 4px var(--tw-shadow-color)}
.shadow-\[0_0_4px_\#c4d3ca\],.shadow-\[0_0_4px_\#eb9f82\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_4px_\#eb9f82\]{--tw-shadow:0 0 4px rgb(var(--nx-mtg-r));--tw-shadow-colored:0 0 4px var(--tw-shadow-color)}
.shadow-\[0_0_4px_\#f8e7b9\]{--tw-shadow:0 0 4px rgb(var(--nx-mtg-w));--tw-shadow-colored:0 0 4px var(--tw-shadow-color)}
.shadow-\[0_0_4px_\#f8e7b9\],.shadow-\[0_0_50px_rgba\(0\2c 0\2c 0\2c 0\.6\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-\[0_0_50px_rgba\(0\2c 0\2c 0\2c 0\.6\)\]{--tw-shadow:0 0 50px #0009;--tw-shadow-colored:0 0 50px var(--tw-shadow-color)}
.shadow-inner{--tw-shadow:inset 0 2px 4px 0 #0000000d;--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color)}
.shadow-inner,.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}
.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-neon-blue{--tw-shadow:0 0 8px rgb(var(--nx-accent)/0.6);--tw-shadow-colored:0 0 8px var(--tw-shadow-color)}
.shadow-neon-blue,.shadow-neon-error{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-neon-error{--tw-shadow:0 0 8px rgb(var(--nx-error)/0.6);--tw-shadow-colored:0 0 8px var(--tw-shadow-color)}
.shadow-neon-violet{--tw-shadow:0 0 8px #9d4edd99;--tw-shadow-colored:0 0 8px var(--tw-shadow-color)}
.shadow-neon-violet,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}
.shadow-xl{--tw-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.shadow-mtg-b{--tw-shadow-color:rgb(var(--nx-mtg-b));--tw-shadow:var(--tw-shadow-colored)}
.shadow-mtg-c{--tw-shadow-color:#ccc;--tw-shadow:var(--tw-shadow-colored)}
.shadow-mtg-g{--tw-shadow-color:rgb(var(--nx-mtg-g));--tw-shadow:var(--tw-shadow-colored)}
.shadow-mtg-r{--tw-shadow-color:rgb(var(--nx-mtg-r));--tw-shadow:var(--tw-shadow-colored)}
.shadow-mtg-u{--tw-shadow-color:rgb(var(--nx-mtg-u));--tw-shadow:var(--tw-shadow-colored)}
.shadow-mtg-w{--tw-shadow-color:rgb(var(--nx-mtg-w));--tw-shadow:var(--tw-shadow-colored)}
.outline-none{outline:2px solid #0000;outline-offset:2px}
.outline{outline-style:solid}
.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)}
.ring-1,.ring-2{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}
.ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)}
.ring-mtg-b{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--nx-mtg-b)/var(--tw-ring-opacity,1))}
.ring-mtg-c{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--nx-mtg-c)/var(--tw-ring-opacity,1))}
.ring-mtg-g{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--nx-mtg-g)/var(--tw-ring-opacity,1))}
.ring-mtg-r{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--nx-mtg-r)/var(--tw-ring-opacity,1))}
.ring-mtg-u{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--nx-mtg-u)/var(--tw-ring-opacity,1))}
.ring-mtg-w{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--nx-mtg-w)/var(--tw-ring-opacity,1))}
.ring-nexus-blue{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--nx-accent)/var(--tw-ring-opacity,1))}
.ring-nexus-error{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--nx-error)/var(--tw-ring-opacity,1))}
.blur{--tw-blur:blur(8px)}
.blur,.blur-3xl{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}
.blur-3xl{--tw-blur:blur(64px)}
.blur-\[100px\]{--tw-blur:blur(100px)}
.blur-\[100px\],.blur-\[120px\]{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}
.blur-\[120px\]{--tw-blur:blur(120px)}
.brightness-\[0\.8\]{--tw-brightness:brightness(0.8)}
.brightness-\[0\.8\],.drop-shadow{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}
.drop-shadow{--tw-drop-shadow:drop-shadow(0 1px 2px #0000001a) drop-shadow(0 1px 1px #0000000f)}
.drop-shadow-\[0_0_15px_rgba\(255\2c 94\2c 91\2c 0\.5\)\]{--tw-drop-shadow:drop-shadow(0 0 15px #ff5e5b80)}
.drop-shadow-\[0_0_15px_rgba\(255\2c 94\2c 91\2c 0\.5\)\],.drop-shadow-\[0_0_15px_rgba\(88\2c 101\2c 242\2c 0\.5\)\]{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}
.drop-shadow-\[0_0_15px_rgba\(88\2c 101\2c 242\2c 0\.5\)\]{--tw-drop-shadow:drop-shadow(0 0 15px #5865f280)}
.drop-shadow-\[0_0_8px_rgba\(0\2c 225\2c 255\2c 0\.6\)\]{--tw-drop-shadow:drop-shadow(0 0 8px rgb(var(--nx-accent)/0.6))}
.drop-shadow-\[0_0_8px_rgba\(0\2c 225\2c 255\2c 0\.6\)\],.drop-shadow-lg{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}
.drop-shadow-lg{--tw-drop-shadow:drop-shadow(0 10px 8px #0000000a) drop-shadow(0 4px 3px #0000001a)}
.drop-shadow-md{--tw-drop-shadow:drop-shadow(0 4px 3px #00000012) drop-shadow(0 2px 2px #0000000f)}
.drop-shadow-md,.drop-shadow-sm{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}
.drop-shadow-sm{--tw-drop-shadow:drop-shadow(0 1px 1px #0000000d)}
.grayscale{--tw-grayscale:grayscale(100%)}
.grayscale,.grayscale-0{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}
.grayscale-0{--tw-grayscale:grayscale(0)}
.invert{--tw-invert:invert(100%)}
.filter,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}
.backdrop-blur{--tw-backdrop-blur:blur(8px)}
.backdrop-blur,.backdrop-blur-md{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}
.backdrop-blur-md{--tw-backdrop-blur:blur(12px)}
.backdrop-blur-sm{--tw-backdrop-blur:blur(4px)}
.backdrop-blur-sm,.backdrop-blur-xl{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}
.backdrop-blur-xl{--tw-backdrop-blur:blur(24px)}
.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}
.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}
.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}
.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}
.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}
.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}
.duration-1000{transition-duration:1s}
.duration-200{transition-duration:.2s}
.duration-300{transition-duration:.3s}
.duration-500{transition-duration:.5s}
.duration-700{transition-duration:.7s}
.duration-\[10s\]{transition-duration:10s}
.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}
.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}
.\[animation-delay\:2s\]{animation-delay:2s}
.last\:mb-0:last-child{margin-bottom:0}
.last\:border-0:last-child{border-width:0}
.last\:pb-0:last-child{padding-bottom:0}
.hover\:z-50:hover{z-index:50}
.hover\:z-\[100\]:hover{z-index:100}
.hover\:-translate-y-1:hover{--tw-translate-y:-0.25rem}
.hover\:-translate-y-1:hover,.hover\:-translate-y-2:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.hover\:-translate-y-2:hover{--tw-translate-y:-0.5rem}
.hover\:-translate-y-8:hover{--tw-translate-y:-2rem}
.hover\:-translate-y-8:hover,.hover\:scale-105:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}
.hover\:scale-110:hover{--tw-scale-x:1.1;--tw-scale-y:1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.hover\:space-x-2:hover>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}
.hover\:border-amber-500\/50:hover{border-color:#f59e0b80}
.hover\:border-brand-cardkingdom:hover{--tw-border-opacity:1;border-color:rgb(234 179 8/var(--tw-border-opacity,1))}
.hover\:border-brand-tcgplayer:hover{--tw-border-opacity:1;border-color:rgb(22 163 74/var(--tw-border-opacity,1))}
.hover\:border-nexus-blue:hover{--tw-border-opacity:1;border-color:rgb(var(--nx-accent)/var(--tw-border-opacity,1))}
.hover\:border-nexus-blue\/50:hover{border-color:rgb(var(--nx-accent)/0.5)}
.hover\:border-nexus-error:hover{--tw-border-opacity:1;border-color:rgb(var(--nx-error)/var(--tw-border-opacity,1))}
.hover\:border-nexus-error\/50:hover{border-color:rgb(var(--nx-error)/0.5)}
.hover\:border-nexus-success:hover{--tw-border-opacity:1;border-color:rgb(var(--nx-success)/var(--tw-border-opacity,1))}
.hover\:border-nexus-surface:hover{--tw-border-opacity:1;border-color:rgb(var(--nx-surface)/var(--tw-border-opacity,1))}
.hover\:border-nexus-surface-hover:hover{--tw-border-opacity:1;border-color:rgb(var(--nx-surface-hover)/var(--tw-border-opacity,1))}
.hover\:border-nexus-violet:hover{--tw-border-opacity:1;border-color:rgb(var(--nx-violet)/var(--tw-border-opacity,1))}
.hover\:border-nexus-warning:hover{--tw-border-opacity:1;border-color:rgb(var(--nx-warning)/var(--tw-border-opacity,1))}
.hover\:border-slate-700:hover{--tw-border-opacity:1;border-color:rgb(var(--nx-slate-700)/var(--tw-border-opacity,1))}
.hover\:border-violet-500\/50:hover{border-color:#8b5cf680}
.hover\:border-white:hover{--tw-border-opacity:1;border-color:rgb(var(--nx-hair)/var(--tw-border-opacity,1))}
.hover\:bg-discord-hover:hover{--tw-bg-opacity:1;background-color:rgb(71 82 196/var(--tw-bg-opacity,1))}
.hover\:bg-emerald-700:hover{--tw-bg-opacity:1;background-color:rgb(4 120 87/var(--tw-bg-opacity,1))}
.hover\:bg-fuchsia-500:hover{--tw-bg-opacity:1;background-color:rgb(217 70 239/var(--tw-bg-opacity,1))}
.hover\:bg-fuchsia-600:hover{--tw-bg-opacity:1;background-color:rgb(192 38 211/var(--tw-bg-opacity,1))}
.hover\:bg-kofi-hover:hover{--tw-bg-opacity:1;background-color:rgb(229 83 80/var(--tw-bg-opacity,1))}
.hover\:bg-nexus-base:hover{--tw-bg-opacity:1;background-color:rgb(var(--nx-base)/var(--tw-bg-opacity,1))}
.hover\:bg-nexus-blue:hover{--tw-bg-opacity:1;background-color:rgb(var(--nx-accent)/var(--tw-bg-opacity,1))}
.hover\:bg-nexus-blue\/20:hover{background-color:rgb(var(--nx-accent)/0.2)}
.hover\:bg-nexus-blue\/30:hover{background-color:rgb(var(--nx-accent)/0.3)}
.hover\:bg-nexus-blue\/5:hover{background-color:rgb(var(--nx-accent)/0.05)}
.hover\:bg-nexus-blue\/80:hover{background-color:rgb(var(--nx-accent)/0.8)}
.hover\:bg-nexus-error\/20:hover{background-color:rgb(var(--nx-error)/0.2)}
.hover\:bg-nexus-error\/30:hover{background-color:rgb(var(--nx-error)/0.3)}
.hover\:bg-nexus-error\/40:hover{background-color:rgb(var(--nx-error)/0.4)}
.hover\:bg-nexus-error\/5:hover{background-color:rgb(var(--nx-error)/0.05)}
.hover\:bg-nexus-error\/80:hover{background-color:rgb(var(--nx-error)/0.8)}
.hover\:bg-nexus-success\/20:hover{background-color:rgb(var(--nx-success)/0.2)}
.hover\:bg-nexus-surface:hover{--tw-bg-opacity:1;background-color:rgb(var(--nx-surface)/var(--tw-bg-opacity,1))}
.hover\:bg-nexus-surface-hover:hover{--tw-bg-opacity:1;background-color:rgb(var(--nx-surface-hover)/var(--tw-bg-opacity,1))}
.hover\:bg-nexus-violet:hover{--tw-bg-opacity:1;background-color:rgb(var(--nx-violet)/var(--tw-bg-opacity,1))}
.hover\:bg-nexus-violet\/80:hover{background-color:rgb(var(--nx-violet)/0.8)}
.hover\:bg-nexus-warning\/80:hover{background-color:rgb(var(--nx-warning)/0.8)}
.hover\:bg-slate-800:hover{--tw-bg-opacity:1;background-color:rgb(var(--nx-slate-800)/var(--tw-bg-opacity,1))}
.hover\:bg-violet-900\/50:hover{background-color:#4c1d9580}
.hover\:bg-white:hover{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}
.hover\:text-nexus-base:hover{--tw-text-opacity:1;color:rgb(var(--nx-base)/var(--tw-text-opacity,1))}
.hover\:text-nexus-blue:hover{--tw-text-opacity:1;color:rgb(var(--nx-accent)/var(--tw-text-opacity,1))}
.hover\:text-nexus-error:hover{--tw-text-opacity:1;color:rgb(var(--nx-error)/var(--tw-text-opacity,1))}
.hover\:text-nexus-success\/80:hover{color:rgb(var(--nx-success)/0.8)}
.hover\:text-nexus-text:hover{--tw-text-opacity:1;color:rgb(var(--nx-text)/var(--tw-text-opacity,1))}
.hover\:text-nexus-violet:hover{--tw-text-opacity:1;color:rgb(var(--nx-violet)/var(--tw-text-opacity,1))}
.hover\:text-nexus-warning:hover{--tw-text-opacity:1;color:rgb(var(--nx-warning)/var(--tw-text-opacity,1))}
.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(var(--nx-ink)/var(--tw-text-opacity,1))}
.hover\:underline:hover{text-decoration-line:underline}
.hover\:opacity-100:hover{opacity:1}
.hover\:opacity-90:hover{opacity:.9}
.hover\:opacity-95:hover{opacity:.95}
.hover\:shadow-\[0_0_15px_rgba\(0\2c 225\2c 255\2c 0\.2\)\]:hover{--tw-shadow:0 0 15px rgb(var(--nx-accent)/0.2);--tw-shadow-colored:0 0 15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.hover\:shadow-\[0_0_30px_rgba\(139\2c 92\2c 246\2c 0\.1\)\]:hover{--tw-shadow:0 0 30px #8b5cf61a;--tw-shadow-colored:0 0 30px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.hover\:shadow-\[0_0_30px_rgba\(245\2c 158\2c 11\2c 0\.05\)\]:hover{--tw-shadow:0 0 30px #f59e0b0d;--tw-shadow-colored:0 0 30px var(--tw-shadow-color)}
.hover\:shadow-\[0_0_30px_rgba\(245\2c 158\2c 11\2c 0\.05\)\]:hover,.hover\:shadow-lg:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}
.hover\:shadow-neon-blue:hover{--tw-shadow:0 0 8px rgb(var(--nx-accent)/0.6);--tw-shadow-colored:0 0 8px var(--tw-shadow-color)}
.hover\:shadow-neon-blue:hover,.hover\:shadow-neon-error:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.hover\:shadow-neon-error:hover{--tw-shadow:0 0 8px rgb(var(--nx-error)/0.6);--tw-shadow-colored:0 0 8px var(--tw-shadow-color)}
.hover\:shadow-neon-violet:hover{--tw-shadow:0 0 8px #9d4edd99;--tw-shadow-colored:0 0 8px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.hover\:ring-2:hover{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}
.hover\:ring-nexus-blue:hover{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--nx-accent)/var(--tw-ring-opacity,1))}
.hover\:drop-shadow-\[0_0_8px_rgba\(0\2c 225\2c 255\2c 0\.6\)\]:hover{--tw-drop-shadow:drop-shadow(0 0 8px rgb(var(--nx-accent)/0.6))}
.hover\:drop-shadow-\[0_0_8px_rgba\(0\2c 225\2c 255\2c 0\.6\)\]:hover,.hover\:grayscale-0:hover{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}
.hover\:grayscale-0:hover{--tw-grayscale:grayscale(0)}
.focus\:border-nexus-blue:focus{--tw-border-opacity:1;border-color:rgb(var(--nx-accent)/var(--tw-border-opacity,1))}
.focus\:border-nexus-violet:focus{--tw-border-opacity:1;border-color:rgb(var(--nx-violet)/var(--tw-border-opacity,1))}
.focus\:border-nexus-warning:focus{--tw-border-opacity:1;border-color:rgb(var(--nx-warning)/var(--tw-border-opacity,1))}
.active\:scale-95:active{--tw-scale-x:.95;--tw-scale-y:.95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.disabled\:opacity-30:disabled{opacity:.3}
.disabled\:opacity-50:disabled{opacity:.5}
.group:hover .group-hover\:-translate-x-1{--tw-translate-x:-0.25rem}
.group:hover .group-hover\:-translate-x-1,.group:hover .group-hover\:-translate-y-4{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.group:hover .group-hover\:-translate-y-4{--tw-translate-y:-1rem}
.group:hover .group-hover\:translate-x-6{--tw-translate-x:1.5rem}
.group:hover .group-hover\:translate-x-6,.group:hover .group-hover\:translate-y-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.group:hover .group-hover\:translate-y-1{--tw-translate-y:0.25rem}
.group:hover .group-hover\:rotate-180{--tw-rotate:180deg}
.group:hover .group-hover\:rotate-180,.group:hover .group-hover\:rotate-3{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.group:hover .group-hover\:rotate-3{--tw-rotate:3deg}
.group:hover .group-hover\:scale-105{--tw-scale-x:1.05;--tw-scale-y:1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
.group:hover .group-hover\:border-nexus-blue\/70{border-color:rgb(var(--nx-accent)/0.7)}
.group:hover .group-hover\:bg-nexus-base\/10{background-color:rgb(var(--nx-base)/0.1)}
.group:hover .group-hover\:text-amber-400{--tw-text-opacity:1;color:rgb(var(--nx-rare)/var(--tw-text-opacity,1))}
.group:hover .group-hover\:text-brand-cardkingdom{--tw-text-opacity:1;color:rgb(234 179 8/var(--tw-text-opacity,1))}
.group:hover .group-hover\:text-brand-tcgplayer{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}
.group:hover .group-hover\:text-nexus-blue{--tw-text-opacity:1;color:rgb(var(--nx-accent)/var(--tw-text-opacity,1))}
.group:hover .group-hover\:text-nexus-violet{--tw-text-opacity:1;color:rgb(var(--nx-violet)/var(--tw-text-opacity,1))}
.group:hover .group-hover\:text-violet-400{--tw-text-opacity:1;color:rgb(var(--nx-violet-lit)/var(--tw-text-opacity,1))}
.group:hover .group-hover\:opacity-100{opacity:1}
.group:hover .group-hover\:opacity-80{opacity:.8}
.group:hover .group-hover\:opacity-90{opacity:.9}
.group:hover .group-hover\:shadow-neon-blue{--tw-shadow:0 0 8px rgb(var(--nx-accent)/0.6);--tw-shadow-colored:0 0 8px var(--tw-shadow-color)}
.group:hover .group-hover\:shadow-neon-blue,.group:hover .group-hover\:shadow-neon-error{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.group:hover .group-hover\:shadow-neon-error{--tw-shadow:0 0 8px rgb(var(--nx-error)/0.6);--tw-shadow-colored:0 0 8px var(--tw-shadow-color)}
/* === sm: @media (min-width:640px) === */
@media (min-width:640px){
  .sm\:w-20{width:5rem}
  .sm\:w-48{width:12rem}
  .sm\:w-56{width:14rem}
  .sm\:w-\[130px\]{width:130px}
  .sm\:w-\[480px\]{width:480px}
  .sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .sm\:flex-row{flex-direction:row}
  .sm\:text-\[10px\]{font-size:10px}
  .sm\:text-base{font-size:1rem;line-height:1.5rem}
}
/* === md: @media (min-width:768px) === */
@media (min-width:768px){
  .md\:right-8{right:2rem}
  .md\:col-span-1{grid-column:span 1/span 1}
  .md\:col-span-2{grid-column:span 2/span 2}
  .md\:mb-0{margin-bottom:0}
  .md\:flex{display:flex}
  .md\:h-16{height:4rem}
  .md\:h-52{height:13rem}
  .md\:w-1\/2{width:50%}
  .md\:w-16{width:4rem}
  .md\:w-32{width:8rem}
  .md\:w-5\/12{width:41.666667%}
  .md\:w-64{width:16rem}
  .md\:w-7\/12{width:58.333333%}
  .md\:w-\[150px\]{width:150px}
  .md\:w-\[160px\]{width:160px}
  .md\:w-\[680px\]{width:680px}
  .md\:w-auto{width:auto}
  .md\:w-full{width:100%}
  .md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
  .md\:flex-row{flex-direction:row}
  .md\:flex-col{flex-direction:column}
  .md\:items-start{align-items:flex-start}
  .md\:items-end{align-items:flex-end}
  .md\:gap-6{gap:1.5rem}
  .md\:gap-8{gap:2rem}
  .md\:-space-x-16>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(-4rem*var(--tw-space-x-reverse));margin-left:calc(-4rem*(1 - var(--tw-space-x-reverse)))}
  .md\:border-r{border-right-width:1px}
  .md\:p-10{padding:2.5rem}
  .md\:p-12{padding:3rem}
  .md\:p-8{padding:2rem}
  .md\:px-10{padding-left:2.5rem;padding-right:2.5rem}
  .md\:px-6{padding-left:1.5rem;padding-right:1.5rem}
  .md\:px-8{padding-left:2rem;padding-right:2rem}
  .md\:pb-32{padding-bottom:8rem}
  .md\:pt-24{padding-top:6rem}
  .md\:text-left{text-align:left}
  .md\:text-3xl{font-size:1.875rem;line-height:2.25rem}
  .md\:text-4xl{font-size:2.25rem;line-height:2.5rem}
  .md\:text-5xl{font-size:3rem;line-height:1}
  .md\:text-6xl{font-size:3.75rem;line-height:1}
  .md\:text-\[10px\]{font-size:10px}
  .md\:text-base{font-size:1rem;line-height:1.5rem}
  .md\:text-lg{font-size:1.125rem;line-height:1.75rem}
  .md\:text-sm{font-size:.875rem;line-height:1.25rem}
  .md\:text-xl{font-size:1.25rem;line-height:1.75rem}
  .md\:text-xs{font-size:.75rem;line-height:1rem}
}
/* === lg: @media (min-width:1024px) === */
@media (min-width:1024px){
  .lg\:ml-4{margin-left:1rem}
  .lg\:flex{display:flex}
  .lg\:hidden{display:none}
  .lg\:h-\[28rem\]{height:28rem}
  .lg\:h-\[550px\]{height:550px}
  .lg\:w-1\/2{width:50%}
  .lg\:w-72{width:18rem}
  .lg\:w-\[70\%\]{width:70%}
  .lg\:w-fit{width:-moz-fit-content;width:fit-content}
  .lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}
  .lg\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}
  .lg\:flex-row{flex-direction:row}
  .lg\:gap-8{gap:2rem}
  .lg\:p-10{padding:2.5rem}
  .lg\:p-6{padding:1.5rem}
  .lg\:p-8{padding:2rem}
  .lg\:px-8{padding-left:2rem;padding-right:2rem}
  .lg\:text-left{text-align:left}
  .lg\:text-5xl{font-size:3rem;line-height:1}
  .lg\:text-7xl{font-size:4.5rem;line-height:1}
  .lg\:text-\[11px\]{font-size:11px}
  .lg\:text-base{font-size:1rem;line-height:1.5rem}
  .lg\:text-sm{font-size:.875rem;line-height:1.25rem}
}
/* === xl: @media (min-width:1280px) === */
@media (min-width:1280px){
  .xl\:col-span-3{grid-column:span 3/span 3}
  .xl\:mt-0{margin-top:0}
  .xl\:w-\[20\%\]{width:20%}
  .xl\:w-\[30\%\]{width:30%}
  .xl\:w-auto{width:auto}
  .xl\:max-w-\[300px\]{max-width:300px}
  .xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
  .xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}
  .xl\:flex-row{flex-direction:row}
  .xl\:items-center{align-items:center}
  .xl\:justify-end{justify-content:flex-end}
  .xl\:border-b-0{border-bottom-width:0}
  .xl\:border-r{border-right-width:1px}
  .xl\:p-8{padding:2rem}
}
/* === 2xl: @media (min-width:1536px) === */
@media (min-width:1536px){
  .\32xl\:w-1\/3{width:33.333333%}
  .\32xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .\32xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}
  .\32xl\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}
  .\32xl\:gap-x-12{-moz-column-gap:3rem;column-gap:3rem}
}
/* === HAND-ADDED SINCE DETACH — new rules accumulate here, semantic names === */
/* Playtest hand fan: stacking order via --fan-z (set inline per card),
   alternating tilt on hover. The .transform class applies the --tw-* chain,
   so the tilt rules only need to set the var. */
.fan-card{z-index:var(--fan-z,0)}
.fan-tilt-l:hover{--tw-rotate:-2deg}
.fan-tilt-r:hover{--tw-rotate:2deg}
/* Cards-tab price badge. Own rule rather than utilities because `bottom-1.5`
   does NOT exist in this stylesheet (`left-1.5` does) — the badge lost its
   offset and rendered over the card title. Positioning lives here so it
   cannot silently break again. */
/* Skip link (2026-09-05). Off-screen until focused; the first Tab on any page
   reveals it above the sticky header (z-50) so keyboard users can jump the nav. */
.nexus-skip{position:absolute;left:-999px;top:.5rem;z-index:60;padding:.5rem .875rem;border-radius:.5rem;background:rgb(var(--nx-accent));color:#fff;font-weight:700;font-size:.875rem;text-decoration:none}
.nexus-skip:focus,.nexus-skip:focus-visible{left:.5rem;outline:2px solid #fff;outline-offset:2px}
/* Multi-line text that keeps its line breaks (confirm dialogs, deck descriptions). */
.nexus-prewrap{white-space:pre-line;overflow-wrap:anywhere}
.nexus-price-badge{position:absolute;bottom:.375rem;left:.375rem;z-index:20;
  pointer-events:none;padding:.125rem .375rem;border-radius:.375rem;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;
  font-weight:700;line-height:1.2;color:rgb(var(--nx-rare));background:rgb(var(--nx-card)/.85);
  border:1px solid rgb(var(--nx-muted)/.35);backdrop-filter:blur(4px)}

/* Set filter (2026-08-24). The <select class="nexus-field nexus-field--md"> is now populated from
   get_filterable_sets() instead of ~40 hardcoded options, and a native select
   auto-sizes to its LONGEST option — "The Lord of the Rings: Tales of
   Middle-earth (LTR)" stretched the control to 346px and shoved the rest of
   the filter bar sideways. Pin the closed width and ellipsise the label; the
   opened dropdown is drawn by the browser and still shows full set names. */
.nexus-set-select{width:172px;max-width:172px;text-overflow:ellipsis}

/* Printing picker (2026-08-24). Chevron > "Change printing", and the per-copy
   basic-land art layout. auto-fill/minmax rather than fixed breakpoints: the
   grid holds anywhere from 1 tile (most cards) to 60 (a page of Forest's 946),
   and should reflow to whatever the glass modal's width allows. */
.nexus-printing-grid{display:grid;gap:1rem;
  grid-template-columns:repeat(auto-fill,minmax(148px,1fr))}

.nexus-printing-tile{position:relative;display:flex;flex-direction:column;
  border-radius:.75rem;overflow:hidden;background:rgb(var(--nx-card));
  border:1px solid rgb(var(--nx-muted)/.22);transition:border-color .15s,
  box-shadow .15s,transform .15s}
.nexus-printing-tile[onclick]{cursor:pointer}
.nexus-printing-tile[onclick]:hover{transform:translateY(-2px);
  border-color:rgb(var(--nx-accent)/.6);box-shadow:0 0 18px rgb(var(--nx-accent)/.28)}
.nexus-printing-tile.is-current{border-color:rgb(var(--nx-accent)/.75);
  box-shadow:0 0 0 1px rgb(var(--nx-accent)/.35),0 0 20px rgb(var(--nx-accent)/.25)}
.nexus-printing-tile.is-assigned{border-color:rgb(var(--nx-violet-lit)/.75);
  box-shadow:0 0 0 1px rgb(var(--nx-violet-lit)/.35),0 0 20px rgb(var(--nx-violet-lit)/.25)}

.nexus-printing-badge{position:absolute;top:.375rem;left:.375rem;z-index:10;
  padding:.125rem .375rem;border-radius:.375rem;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9px;
  font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:rgb(var(--nx-card));
  background:rgb(var(--nx-accent)/.9);border:1px solid rgb(var(--nx-accent)/1)}

.nexus-printing-img{width:100%;aspect-ratio:5/7;object-fit:cover;display:block}

.nexus-printing-meta{display:flex;flex-direction:column;gap:.3rem;
  padding:.5rem .55rem .6rem;font-size:10px;line-height:1.35}

.nexus-finish-row{display:flex;flex-wrap:wrap;justify-content:center;
  gap:.25rem;margin-top:.15rem}
.nexus-finish-chip{padding:.15rem .4rem;border-radius:.3rem;font-size:9px;
  font-weight:700;line-height:1.3;cursor:pointer;color:rgb(var(--nx-muted));
  background:rgb(var(--nx-slate-800)/.9);border:1px solid rgb(var(--nx-muted)/.28);
  transition:color .12s,border-color .12s,background-color .12s}
.nexus-finish-chip:hover{color:rgb(var(--nx-slate-200));border-color:rgb(var(--nx-muted)/.55)}
.nexus-finish-chip.is-active{color:rgb(var(--nx-card));background:rgb(var(--nx-rare));
  border-color:rgb(var(--nx-rare))}

.nexus-printing-stepper{display:flex;align-items:center;justify-content:center;
  gap:.4rem;margin-top:.2rem}
.nexus-step-btn{width:1.35rem;height:1.35rem;display:flex;align-items:center;
  justify-content:center;border-radius:.3rem;font-size:12px;font-weight:700;
  line-height:1;cursor:pointer;color:rgb(var(--nx-slate-300));background:rgb(var(--nx-slate-800)/.95);
  border:1px solid rgb(var(--nx-muted)/.3);transition:color .12s,border-color .12s}
.nexus-step-btn:hover:not(:disabled){color:#fff;border-color:rgb(var(--nx-accent)/.7)}
.nexus-step-btn:disabled{opacity:.3;cursor:not-allowed}
.nexus-step-count{min-width:1.4rem;text-align:center;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;
  font-weight:700;color:rgb(var(--nx-slate-500))}
.nexus-step-count.is-set{color:rgb(var(--nx-violet-lit))}

/* === 2026-08-24 (Chad testing round) — rules written per THE RULES #1 above.
   Tailwind is gone and there is no build step, so every class below is a real
   rule, named semantically, and no width is composed at runtime (#2). === */

/* Session Zero "Guide Me" tile. 7 beginner archetypes in a 3-col grid landed
   3/3/1; sized for exactly 4 per row inside a flex-wrap/justify-center parent
   this gives 4 on top and the remaining 3 centred beneath — a pyramid — and it
   re-centres at any count, so curating an 8th archetype cannot orphan a tile.
   Height is condensed here too (was h-44 / md:h-52). */
.nexus-wizard-tile{width:100%;height:9rem}
@media (min-width:640px){.nexus-wizard-tile{width:calc(50% - .5rem)}}
@media (min-width:768px){.nexus-wizard-tile{height:10rem}}
@media (min-width:1024px){.nexus-wizard-tile{width:calc(25% - .75rem)}}
/* Three lines, not two: at 4-up the tiles are narrow enough that a 2-line clamp
   cut most blurbs mid-sentence. (line-clamp-3 has no Tailwind-era rule here.) */
.nexus-wizard-blurb{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}

/* Discover filter bar stability (#2 "mana buttons misaligned based on number of
   cards listed"). Three things moved those pips, all fixed here:
   1. the results grid growing tall enough to summon a viewport scrollbar
      narrowed the page ~15px and re-centred the whole bar -> reserve the
      gutter permanently so row count can never change layout width;
   2. the "x Clear" button is display:none until a colour is picked, and
      widened #hub-color-filters when it appeared -> reserve its slot;
   The bar is still lg:w-fit + justify-center (content-driven AND centred), which
   is what turns any width change into sideways movement -- that styling is kept
   deliberately, because it is the centred-pill look; (1) and (2) remove the two
   things that were actually changing the width. */
html{scrollbar-gutter:stable}
/* flex-start only from md up, where the box is content-sized and centring
   would be a no-op anyway. Below md the box is w-full, so the markup's
   justify-center splits the leftover 14px evenly instead of leaving it all
   on the right -- and row one is always exactly the six pips (Clear is
   display:none, or wrapped to row two), so centring can never move them. */
@media (min-width:768px){#hub-color-filters{justify-content:flex-start}}

/* Amended 2026-08-25. Reserving the slot is right only from md up, and only
   because the box is content-sized there. Once the coarse-pointer floor took
   the buttons to 44px the reserved slot stopped fitting beside the pips on a
   phone, so it wrapped -- an invisible 44px button sitting on a flex row of
   its own, making the pip box 106px tall to hold 44px of pips (measured at
   390px: rows at y=281.6 and y=329.6, the second holding nothing but the
   hidden button).
   Below md the box is w-full, so its width is dictated by the bar and is
   already immune to what it contains -- there is nothing to reserve. Giving
   the button a flex line of its own makes row one exactly the six pips at
   every width, so it can come and go freely: no dead row at rest, and nothing
   that can shift a pip. (Letting it share the pips' line is what moved them
   41px at 500px, x 108 -> 67.2, when its own line's centring counted it.) */
#hub-color-clear-btn{display:inline-flex;visibility:hidden}
#hub-color-clear-btn.is-visible{visibility:visible}
@media (max-width:767px){
  #hub-color-clear-btn{display:none;visibility:visible}
  #hub-color-clear-btn.is-visible{display:inline-flex;flex-basis:100%}
}

/* Per-copy printing split (#1). A card whose copies are spread across several
   printings renders one tile per printing; this marks the set on each so two
   Swamps of different art are told apart at a glance. */
.nexus-print-split-badge{position:absolute;top:.25rem;left:.25rem;z-index:10;
  padding:1px 5px;border-radius:.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:9px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:rgb(var(--nx-text));background:rgb(var(--nx-base)/.88);border:1px solid rgb(var(--nx-accent)/.45);
  backdrop-filter:blur(4px);pointer-events:none}
/* ==========================================================================
   DECK HERO — Chromatic Frame + Devotion Rail            (added 2026-08-24)

   Two facts, two carriers, no overlap:
     the frame ring states colour IDENTITY  (which colours this deck may play)
     the bottom rail states pip DEVOTION    (how much of each it actually casts)

   Per rule 2 of this block, nothing here is a runtime-built class name.
   Computed values arrive as inline `style` (segment widths) or as inline
   custom properties (--ident, --identglow, --c) that resolve against the
   *-lit tokens defined on .deck-hero below.

   Why *-lit tokens exist: the mtg-* frame colours (b #a69f9d is a neutral
   grey) are the printed-card palette and effectively vanish as light on a
   #080b12 ground. These are a second, saturated set used ONLY for emitted
   light — rails, glows, frame ring. Pips and bars keep using mtg-*.
   ========================================================================== */
.deck-hero{
  --mtg-w-lit:255,217,138;
  --mtg-u-lit:76,158,232;
  --mtg-b-lit:155,123,196;
  --mtg-r-lit:242,89,60;
  --mtg-g-lit:79,184,107;
  --mtg-c-lit:170,178,190;
  position:relative;
  width:100%;
  min-height:344px;
  overflow:hidden;
  background-color:rgb(var(--nx-base));
  display:flex;
  flex-direction:column;
  gap:26px;
  padding:62px 40px 56px;
  /* The hero sizes its own columns off ITS width, not the window's (2026-09-03).
     Opening a Deck Intelligence drawer puts 436px of fixed chrome (60px rail +
     376px drawer) down the right of #manifest-view as padding-inline-end, so on
     a 1280px window the hero is 829px while a viewport media query still reads
     1280 and keeps the three-column track list. 264 + 34 + 620 + 34 + 300 needs
     1252px; the middle column was squeezed to 57px and its title, bracket card
     and devotion row spilled out over the stat cards on the right.
     container-type is safe here: the hero is already position:relative with
     overflow:hidden, so it was a containing block and a BFC before this, and it
     holds no fixed or sticky descendants that layout containment could trap. */
  container-type:inline-size;
  container-name:deck-hero;
}

/* "Back To Library" rides with the scroll (2026-09-02). A zero-height sticky
   box placed before the hero, so it occupies no flow space, sticks to the
   top of the viewport, and its panel floats 1.5rem below that -- the same
   spot the button used to sit in the hero. The panel carries the geometry
   and the backdrop; the button inside stays a plain .nexus-btn. */
/* top clears the site header, which is itself sticky (88px, z-index 50);
   without the offset the button slid underneath it as soon as the page moved. */
/* ...and clears the read-only banner too: that bar is sticky under the header
   on community decks and precons, and its measured height is published as
   --nexus-banner-h on #manifest-view (05-deck-to-collection.js). Without the
   term, Back To Library sat on top of "Community deck — view only". */
.deck-back-sticky{position:sticky;top:calc(5.5rem + var(--nexus-banner-h,0px));z-index:45;height:0;overflow:visible;
  padding-inline-start:1.5rem;pointer-events:none}
.deck-back-sticky__panel{display:inline-block;margin-block-start:1.5rem;pointer-events:auto;
  border-radius:.5rem;background:rgb(var(--nx-base)/.82);backdrop-filter:blur(8px);
  box-shadow:0 8px 24px rgba(0,0,0,.45)}
.deck-hero-backdrop{position:absolute;inset:0;z-index:0}
.deck-hero-backdrop img{width:100%;height:100%;object-fit:cover;object-position:center;filter:blur(26px) saturate(.72);transform:scale(1.14);opacity:.32}
.deck-hero-veil{position:absolute;inset:0;background:linear-gradient(100deg,rgb(var(--nx-base)) 20%,rgb(var(--nx-base)/.92) 52%,rgb(var(--nx-base)/.74))}

.deck-hero-grid{position:relative;z-index:10;display:grid;grid-template-columns:264px minmax(0,620px) minmax(300px,360px);justify-content:center;gap:34px;align-items:center;width:100%;max-width:1400px;margin-left:auto;margin-right:auto}

.deck-hero-portrait{position:relative}
.deck-hero-zone{font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;font-size:9.5px;letter-spacing:.2em;text-transform:uppercase;color:rgb(var(--nx-muted));text-align:center;margin:0 0 9px}
.deck-hero-frame{position:relative;padding:2px;border-radius:12px;background:var(--ident,rgb(var(--nx-surface-hover)));box-shadow:0 0 36px -6px var(--identglow,transparent),0 16px 44px -16px #000;transition:background .4s ease,box-shadow .4s ease}
.deck-hero-frame img{display:block;width:100%;aspect-ratio:16/11;object-fit:cover;object-position:center;border-radius:10px;background-color:rgb(var(--nx-surface))}
/* Partner / Background pairs get both portraits in the one frame, each half-width
   at 8/11 so the frame keeps its 16/11 silhouette. Set with classList.toggle on a
   literal name — not an interpolated class, per rule 2. */
.deck-hero-frame.is-dual{display:flex;gap:2px}
.deck-hero-frame.is-dual img{flex:1 1 0;min-width:0;width:auto;aspect-ratio:8/11}
.deck-hero-frame.is-dual img:first-of-type{border-radius:10px 2px 2px 10px}
.deck-hero-frame.is-dual img:last-of-type{border-radius:2px 10px 10px 2px}
.deck-hero-frame img[hidden]{display:none}
.deck-hero-pips{position:absolute;left:50%;bottom:-14px;transform:translateX(-50%);display:flex;gap:5px;padding:5px 10px;border-radius:20px;background:rgb(var(--nx-base));border:1px solid rgb(var(--nx-surface-hover))}
.deck-hero-pips:empty{display:none}
.deck-hero-pips img{width:16px;height:16px}

.deck-hero-body{display:flex;flex-direction:column;align-items:flex-start;gap:12px;text-align:left;min-width:0}
/* Neutralise the utility bottom-margins on the title/commander line inside the
   new gap-driven column, so editDeckTitle() can keep emitting its existing
   class list unchanged.
   h2 as well as h1 since 2026-09-04: the deck title was demoted to <h2> (it
   was a second h1 on every page carrying the app shell) and that orphaned this
   rule, letting its mb-2 add 8px on top of the column's 12px gap. Caught by
   the before/after screenshot, not by reading the reset at the top of this
   file — which says h1 and h2 are styled identically, and is true in isolation. */
.deck-hero-body>h1,
.deck-hero-body>h2{margin-bottom:0}
.deck-hero-body>p{margin-bottom:0}

.deck-hero-devotion{display:flex;flex-direction:column;align-items:flex-start;gap:8px}
.deck-hero-devotion[hidden]{display:none}
.deck-hero-devlabel{font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;font-size:9.5px;letter-spacing:.18em;text-transform:uppercase;color:rgb(var(--nx-muted))}

.deck-rail-legend{display:flex;flex-wrap:wrap;gap:15px}
.deck-rail-leg{display:flex;align-items:center;gap:6px;font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;font-size:11px;color:rgb(var(--nx-muted))}
.deck-rail-leg i{display:block;width:9px;height:9px;border-radius:50%;background:rgb(var(--c));box-shadow:0 0 9px rgba(var(--c),.9)}
.deck-rail-leg b{color:rgb(var(--nx-text));font-weight:500}

/* The three analysis cards, promoted out of the full-width row beneath the hero
   into the grid's third column. Narrower than the old row, so the type steps
   down a notch; the ids are unchanged, so calculateManaProfile() still fills them. */
.deck-hero-statcol{position:relative;z-index:10;display:flex;flex-direction:column;gap:12px;min-width:0}
.deck-hero-statcard{background:rgb(var(--nx-base)/.6);border:1px solid rgb(var(--nx-surface-hover)/.75);backdrop-filter:blur(12px);border-radius:12px;padding:13px 15px;transition:border-color .2s ease}
.deck-hero-statcard:hover{border-color:rgb(var(--nx-accent)/.5)}
.deck-hero-statcard h3{margin:0 0 3px;font-size:12.5px;font-weight:700;color:rgb(var(--nx-text));letter-spacing:.01em}
.deck-hero-statcard p{margin:0;font-size:11px;line-height:1.5;color:rgb(var(--nx-muted))}

/* Mana-curve sparkline. get_deck_mana_profile already returns `curve`; nothing
   consumed it until now. Bar heights are computed, so they ride in inline style
   and the only classes are literals. */
.deck-hero-spark{display:flex;align-items:flex-end;gap:3px;margin-top:10px}
.deck-hero-spark-col{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:4px}
.deck-hero-spark-bar{width:100%;border-radius:2px 2px 0 0;background:rgb(var(--nx-accent)/.26);transition:background .2s ease}
.deck-hero-spark-col.is-peak .deck-hero-spark-bar{background:rgb(var(--nx-accent));box-shadow:0 0 9px rgb(var(--nx-accent)/.5)}
.deck-hero-spark-col:hover .deck-hero-spark-bar{background:rgb(var(--nx-accent)/.6)}
.deck-hero-spark-cap{font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;font-size:8.5px;line-height:1;color:rgb(var(--nx-muted))}
.deck-rail{position:absolute;left:0;right:0;bottom:0;height:9px;display:flex;z-index:6}
.deck-rail-seg{position:relative;height:100%;background:rgb(var(--c));box-shadow:0 0 18px 1px rgba(var(--c),.85);transform-origin:bottom;transition:filter .2s ease,transform .2s ease}
.deck-rail-seg:before{content:"";position:absolute;left:0;right:0;bottom:100%;height:34px;background:linear-gradient(to top,rgba(var(--c),.42),rgba(var(--c),0));pointer-events:none}
.deck-rail-seg:after{content:"";position:absolute;right:0;top:0;bottom:0;width:1px;background:rgb(var(--nx-base)/.6)}
.deck-rail-seg:last-child:after{display:none}
.deck-rail:hover .deck-rail-seg{filter:saturate(.35) brightness(.6)}
.deck-rail .deck-rail-seg:hover{filter:none;transform:scaleY(1.9)}

/* A @container size query measures the container's CONTENT box, so these read
   smaller than the window widths they replace. Derived, not guessed: at a
   1240px window the hero content box is 1240 - 15 scrollbar - 60 rail strip
   - 80 padding = 1085, and at a 900px window it is 805. Feeding those two
   numbers back gives the same layout as the old 1240px/900px media queries at
   every window width, and now the switch ALSO fires when a 436px drawer is
   what took the room rather than a small window. (The scrollbar term is ~15px
   on this platform; with overlay scrollbars each switch simply lands ~15px
   later, which is why these are thresholds and not exact parity.)

   The padding drop below moved from 900px to 640px as part of this. It has to:
   it changes the very content box these queries measure, so while it flipped at
   900 the width was NON-MONOTONIC across that window size (a 900px window
   measured 845 but a 901px window measured 806) and no single max-width could
   reproduce the old behaviour on both sides. At 640 it is clear of both
   thresholds. It also stays a MEDIA query on purpose: a container query that
   resizes its own container's padding feeds its own measurement, and padding is
   the one property here that would. */
@container deck-hero (max-width:1085px){
  .deck-hero-grid{grid-template-columns:264px minmax(0,1fr)}
  .deck-hero-statcol{grid-column:1 / -1;flex-direction:row}
  .deck-hero-statcard{flex:1 1 0;min-width:0}
}
@container deck-hero (max-width:805px){
  .deck-hero-grid{grid-template-columns:minmax(0,1fr);gap:22px;justify-items:center}
  .deck-hero-portrait{width:100%;max-width:240px}
  .deck-hero-body{align-items:center;text-align:center}
  .deck-hero-devotion{align-items:center}
  .deck-rail-legend{justify-content:center}
  .deck-hero-statcol{grid-column:auto;flex-direction:column;width:100%}
}
@media (max-width:640px){
  .deck-hero{padding:52px 20px 44px;gap:20px}
}
/* PHONES: Back To Library stops floating and sits in flow above the hero.
   On a 360px screen the deck page already stacks three sticky bands -- the
   88px site header, the 65px read-only banner and the ~150px View/Group/Sort
   toolbar -- and a fourth sticky pill has nowhere to land: it covered the
   banner text, and once the toolbar stuck it covered the View and Group
   selects. Static here, it is the first thing under the header on arrival
   and scrolls away; the bottom rail and the header menu remain. This is a
   phone-only exception to the 2026-09-02 "scrolls with you" ruling, which
   still holds from 641px up. */
@media (max-width:640px){
  .deck-back-sticky{position:static;height:auto;padding:1rem 1.5rem 0}
  .deck-back-sticky__panel{margin-block-start:0}
}
/* The Deck Data Analysis heading row holds a 3xl title and the bracket badge
   on one line. At 320px the badge reads "Computing..." for a second or two
   before the arbiter answers, and that wider state pushed the row to 359px --
   long enough for a phone browser to zoom out and stay there. Wrapping puts
   the badge under the title on phones whatever it says. */
@media (max-width:640px){
  .nexus-analysis-head{flex-wrap:wrap;gap:.75rem}
}
@media (prefers-reduced-motion:reduce){
  .deck-hero-frame,.deck-rail-seg{transition:none}
}

/* === 2026-08-24 (Chad testing round 2) — real rules per THE RULES #1 === */

/* Discover filter panel: pinned only where there is room for it. On phones the
   wrapped panel grows taller than half the viewport and floated OVER the card
   grid while scrolling (Chad's "buttons randomly appearing over collection",
   2026-08-26); below lg it now scrolls away with the page like normal content. */
.nexus-hub-filterbar{position:static}
@media (min-width:1024px){.nexus-hub-filterbar{position:sticky;top:68px}}

/* "Coming soon" hero-bar control (Primer). Deliberately NOT styled like its
   live neighbours: muted surface, dashed border, no hover lift, cursor
   default. A disabled button that still looks clickable is the thing being
   fixed here, so the affordance has to read as pending at a glance. */
.nexus-btn-soon{display:inline-flex;align-items:center;gap:.5rem;
  color:rgb(var(--nx-muted));background:rgb(var(--nx-surface)/.6);
  border:1px dashed rgb(var(--nx-muted)/.45);cursor:default;opacity:.85}
.nexus-btn-soon:hover{color:rgb(var(--nx-muted));border-color:rgb(var(--nx-muted)/.45)}
.nexus-soon-chip{font-size:9px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;padding:.1rem .35rem;border-radius:.3rem;
  color:rgb(var(--nx-card));background:rgb(var(--nx-warning));line-height:1.2}

/* Text-list columns size to the CONTAINER, not the viewport. The list sits in
   the ~70% content pane, so viewport-keyed `2xl:grid-cols-3` gave each column
   288px on a 1905px screen and crushed card names to 45px. 340px is the floor
   at which qty + name + mana + price + set + chevron all fit with the name
   still readable; below that the grid drops to fewer columns instead of
   shrinking the only shrinkable thing in the row. */
.nexus-textlist-grid{display:grid;align-items:start;column-gap:1.5rem;
  grid-template-columns:repeat(auto-fill,minmax(340px,1fr))}

/* Stacked cards: clip the change-border to the sliver that is actually on
   screen. 13.75% = (133.33% card height - 115% negative margin) / 133.33%.
   Without this an add/cut border outlines the card's full footprint straight
   over the cards fanned on top of it. Hovering lifts the card clear, and there
   the whole outline is correct -- that is the one case the full border is
   telling the truth. */
.nexus-stacked-covered.latest-highlight-add::after,
.nexus-stacked-covered.latest-highlight-cut::after,
.nexus-stacked-covered.persist-highlight-add::after,
.nexus-stacked-covered.persist-highlight-cut::after,
.nexus-stacked-covered.tag-change-latest::after,
.nexus-stacked-covered.tag-change-persist::after,
.nexus-stacked-covered.undo-predictive-pulse::after{
  bottom:auto;height:13.75%;border-bottom-left-radius:0;
  border-bottom-right-radius:0}

.nexus-stacked-covered:hover{z-index:40}
.nexus-stacked-covered:hover.latest-highlight-add::after,
.nexus-stacked-covered:hover.latest-highlight-cut::after,
.nexus-stacked-covered:hover.persist-highlight-add::after,
.nexus-stacked-covered:hover.persist-highlight-cut::after,
.nexus-stacked-covered:hover.tag-change-latest::after,
.nexus-stacked-covered:hover.tag-change-persist::after,
.nexus-stacked-covered:hover.undo-predictive-pulse::after{
  bottom:0;height:auto;border-radius:inherit}
/* === 2026-08-24 — Deck share QR. New classes, so rules live here per THE RULES #1.
   The plate is deliberately hard white: a QR must be dark-on-light to scan, and the
   nexus surface tokens are all near-black. Padding is the quiet zone, which is part
   of the QR spec and not decoration — scanners need it. === */
.nexus-qr-plate{background:#fff;padding:12px;border-radius:12px;line-height:0;width:-moz-fit-content;width:fit-content;margin-left:auto;margin-right:auto}
.nexus-qr-plate svg{display:block;width:208px;height:208px}
.nexus-qr-plate img{display:block;width:208px;height:208px;image-rendering:pixelated}
    
/* ==========================================================================
   TYPE SCALE — pinned 2026-08-25. Ten steps, and nothing else.

     text-nexus-tiny   10px / 12px   .05em   micro labels, chips, set codes
     text-xs           12px / 16px           the workhorse; dense UI text
     text-sm           14px / 20px           body copy, list rows, controls
     text-base         16px / 24px           long-form paragraphs
     text-lg           18px / 28px           card titles, panel headings
     text-xl           20px / 28px           section headings
     text-2xl          24px / 32px           view headings
     text-3xl          30px / 36px           page headings
     text-4xl          36px / 40px           hero / modal titles
     text-5xl          48px / 1              display only

   RULES
   1. **10px is the floor.** Nothing renders smaller. 44 elements used
      text-[7px]/[8px]/[9px] before this pass; all were mapped to
      text-nexus-tiny on 2026-08-25.
   2. **No arbitrary sizes.** `text-[Npx]` is banned — 103 usages were mapped
      onto the steps above. Exactly one deliberate exception survives
      (a 22px display heading). If a step is genuinely missing, add it HERE
      with a name, do not inline a pixel value.
   3. Form fields are exempt upward only: `.nexus-field` forces 16px on coarse
      pointers regardless of step, because anything smaller makes iOS Safari
      zoom the viewport on focus. See the FORM FIELDS block.
   ========================================================================== */

/* ==========================================================================
   BUTTONS — one component: 3 sizes x 4 emphases x 5 tones.
   Added 2026-08-25. Replaces 147 one-off button signatures. See LEDGER.md.

   RULE 1: every class below has a real rule, written here at the end,
           semantically named.
   RULE 2: nothing is composed at runtime. Never build a class name
           like nexus-btn--${tone} — JS templates use a literal lookup
           map. A composed name has no hand-written rule behind it and
           there is no build step to generate one, so it renders naked.
   RULE 3: this stays UNLAYERED and last. It must beat the ex-Tailwind
           utilities on source order, so a button can adopt .nexus-btn and
           have its stale px-6/py-2.5/rounded-xl neutralised immediately,
           before those utilities are stripped in a later pass.
           Do NOT wrap this in @layer — a layered rule loses to every
           unlayered one and this whole block would stop working.

   MOBILE: --btn-min drives min-block-size / min-inline-size, never
           width/height, so content can grow a target but never shrink it
           (WCAG 2.5.8 AA = 24px floor). Coarse pointers get 44px.
           No white-space:nowrap — buttons must be allowed to wrap at 320px
           rather than force horizontal overflow.
   ========================================================================== */
.nexus-btn{
  --btn-accent:rgb(var(--nx-accent)); --btn-ink:rgb(var(--nx-accent-ink));
  /* SOLID paints --btn-solid, TINTED writes in --btn-tint. Both default to the
     tone itself, so a tone that needs no split states nothing. They exist
     because the two emphases pull opposite ways: white text ON a fill wants the
     colour DARKER, the same colour AS text on a dark surface wants it LIGHTER.
     One value cannot satisfy both -- measured 2026-09-06, tinted violet was
     3.17 and solid-hover violet 4.34, both under the 4.5 AA bar, from one token. */
  --btn-solid:var(--btn-accent); --btn-tint:var(--btn-accent);
  --btn-hover-into:rgb(var(--nx-accent-ink-hover));
  --btn-radius:.5rem; --btn-pad-y:.5rem; --btn-pad-x:1rem;
  --btn-size:.75rem; --btn-min:2rem;
  display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
  padding:var(--btn-pad-y) var(--btn-pad-x);
  min-block-size:var(--btn-min); min-inline-size:var(--btn-min);
  border-radius:var(--btn-radius); border:1px solid transparent;
  font-family:inherit; font-size:var(--btn-size); font-weight:700;
  line-height:1.2; text-align:center; cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;
  -webkit-user-select:none; user-select:none;
  transition:background-color .15s ease, border-color .15s ease,
             color .15s ease, box-shadow .15s ease, transform .1s ease,
             opacity .15s ease;
}

/* --- size --- */
.nexus-btn--sm{--btn-pad-y:.25rem;--btn-pad-x:.625rem;--btn-size:.625rem;--btn-min:1.75rem;
  letter-spacing:.06em;text-transform:uppercase}
.nexus-btn--md{--btn-pad-y:.5rem;--btn-pad-x:1rem;--btn-size:.75rem;--btn-min:2rem}
.nexus-btn--lg{--btn-pad-y:.625rem;--btn-pad-x:1.25rem;--btn-size:.875rem;--btn-min:2.5rem}

/* --- tone: encodes CONSEQUENCE, not category. No class = blue (default). --- */
.nexus-btn--neutral{--btn-accent:rgb(var(--nx-muted));--btn-ink:rgb(var(--nx-accent-ink))}
/* The three white-ink tones. --btn-ink is #fff in EVERY theme, so their hover
   always darkens, and their tinted text uses the -lit token that exists for
   exactly this (and which the light themes already point back at the dark
   value, so light-mode tinted text stays dark). AA ratios, dark theme:
   danger  fill #e11d48 4.70, hover #bf193d 6.14, tint #fb7185 6.72
   success fill #047857 5.48, hover #03664a 6.99, tint #059669 4.80
   violet  fill #7c3aed 5.70, hover #6931c9 7.28, tint #a78bfa 6.65 */
.nexus-btn--danger {--btn-accent:rgb(var(--nx-error));--btn-ink:#fff;
                    --btn-tint:rgb(var(--nx-error-lit));--btn-hover-into:#000}
.nexus-btn--success{--btn-accent:rgb(var(--nx-success));--btn-ink:#fff;
                    --btn-solid:rgb(var(--nx-success-deep));--btn-hover-into:#000}
.nexus-btn--violet {--btn-accent:rgb(var(--nx-violet));--btn-ink:#fff;
                    --btn-tint:rgb(var(--nx-violet-lit));--btn-hover-into:#000}
.nexus-btn--warning{--btn-accent:rgb(var(--nx-warning));--btn-ink:rgb(var(--nx-accent-ink))}

/* --- emphasis --- */
.nexus-btn--solid{background:var(--btn-solid);color:var(--btn-ink)}
.nexus-btn--solid:hover:not(:disabled){
  /* Toward --btn-hover-into, never hard-coded #fff. The glow still uses the
     TONE so the button keeps its identity while the fill moves away from the
     ink rather than toward it. */
  background:color-mix(in srgb,var(--btn-solid) 85%,var(--btn-hover-into));
  box-shadow:0 0 14px color-mix(in srgb,var(--btn-accent) 55%,transparent);
}
.nexus-btn--tinted{
  background:color-mix(in srgb,var(--btn-accent) 12%,transparent);
  border-color:color-mix(in srgb,var(--btn-accent) 45%,transparent);
  /* The tint pulled 20% toward the page text (the .nexus-front__kind rule):
     darker in the light theme, lighter in the dark. The raw tint failed AA on
     its own 12% wash in 30 of 144 tone x theme x accent x ground cells (light
     cyan 4.21, light warning 3.94, dark success on a panel 4.22), measured by
     axe-core in a real page on 2026-09-10. */
  color:color-mix(in srgb,var(--btn-tint) 80%,rgb(var(--nx-text)));
}
.nexus-btn--tinted:hover:not(:disabled){
  background:color-mix(in srgb,var(--btn-accent) 22%,transparent);
  border-color:var(--btn-accent);
  box-shadow:0 0 12px color-mix(in srgb,var(--btn-accent) 40%,transparent);
}
.nexus-btn--ghost{background:transparent;color:rgb(var(--nx-muted))}
/* --- state: lit. An on/off button that is ON (Group Same Cards, Show What I
   Own, Only Show Cards I Own, the selection actions once a card is picked)
   keeps the tinted look and adds the halo the hover state already draws, so
   "on" reads at rest without the pointer. One rule, used by every toggle
   through paintToggleButton() -- never a per-button glow. Added 2026-09-02. --- */
.nexus-btn.is-lit{box-shadow:0 0 12px color-mix(in srgb,var(--btn-accent) 45%,transparent);
  border-color:var(--btn-accent)}
.nexus-btn--ghost:hover:not(:disabled){
  background:rgb(var(--nx-surface-hover));color:rgb(var(--nx-text));
  border-color:color-mix(in srgb,var(--btn-accent) 35%,transparent);
}
/* A ghost button carrying an explicit tone shows that tone at rest instead of
   the muted default. Without this, --ghost's literal colour swallows the tone
   and the accent only ever appears on hover, which reads as dead chrome.
   Two classes beat --ghost's one, and the :hover rule (three) still wins, so
   the brighten-on-hover behaviour is unchanged. Added for the sign-in
   "Forgot your password?" control; extend to other tones when one needs it. */
.nexus-btn--ghost.nexus-btn--violet{color:var(--btn-accent)}
.nexus-btn--menu{
  --btn-pad-x:1rem;--btn-pad-y:.5rem;
  inline-size:100%;justify-content:flex-start;border-radius:0;
  background:transparent;color:rgb(var(--nx-text));font-weight:600;text-align:start;
}
.nexus-btn--menu:hover:not(:disabled){background:rgb(var(--nx-surface-hover));color:var(--btn-accent)}

/* --- shape --- */
.nexus-btn--pill{--btn-radius:999px}
.nexus-btn--icon{padding:0;aspect-ratio:1;flex:none;--btn-size:1.125rem;font-weight:400}
/* full-width provider buttons: keep the vendor's brand fill, take our geometry */
.nexus-btn--oauth{--btn-size:1.125rem;--btn-min:3rem;inline-size:100%}

/* --- state: one press, one disabled treatment, one focus ring --- */
.nexus-btn:active:not(:disabled){transform:scale(.96)}
.nexus-btn:disabled{opacity:.4;cursor:not-allowed;box-shadow:none}
.nexus-btn:focus-visible{outline:2px solid var(--btn-accent);outline-offset:2px}

/* --- touch: 44px minimum on coarse pointers. Listed with the size classes
       so it wins the --btn-min cascade regardless of which one is applied. --- */
@media (pointer:coarse){
  .nexus-btn,.nexus-btn--sm,.nexus-btn--md,.nexus-btn--lg{--btn-min:2.75rem}
  .nexus-btn--sm{--btn-pad-x:.875rem}
  /* listed last so it survives the --btn-min override above */
  .nexus-btn--oauth{--btn-min:3rem}
}
@media (prefers-reduced-motion:reduce){
  .nexus-btn{transition-duration:.01ms}
  .nexus-btn:active:not(:disabled){transform:none}
}

/* .nexus-btn sets display:inline-flex and this block is LAST in source, so it
   would otherwise beat .hidden{display:none} at equal specificity and unhide
   every hidden button. Restate the override at higher specificity. Any future
   display-affecting utility used on a button needs the same treatment. */
.nexus-btn.hidden{display:none}
/* Same reasoning as above for the responsive hide used by #mobile-menu-btn:
   without this, .nexus-btn{display:inline-flex} wins on source order and the
   hamburger stays visible on desktop, where it becomes a third in-flow child
   of the justify-between header row and shoves the Log In button under the
   absolutely-positioned <nav>. */
@media (min-width:1024px){.nexus-btn.lg\:hidden{display:none}}

/* HEADER ON PHONES (2026-09-03). Every child of the header row is shrink-0,
   so its minimum width is the sum of its parts: brand link with the wordmark
   (221px) + theme, new-deck, bell and avatar at the 44px coarse-pointer
   minimum + hamburger + 40px padding = 480px signed in, 422px as a guest.
   On a 360px phone (Galaxy S20, Firefox) the document laid out at that width
   and the browser zoomed out to fit it, which reads as "off centre". Below
   640px the wordmark and mana dots leave the flow and the gem alone marks the
   brand; the text stays in the DOM, visually hidden, so the link keeps its
   accessible name. The brand link also drops its ghost padding (it is a
   44px gem tile at this width, nothing else) and the row's side padding goes
   from 20px to 16px: gem 44 + nav 194 + hamburger 44 + padding 32 = 314px,
   which fits a 320px phone (iPhone SE class) as well as the 360px S20. */
@media (max-width:639px){
  .nexus-brand__wordmark{position:absolute;width:1px;height:1px;margin:-1px;
    padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);
    white-space:nowrap;border:0}
  .nexus-btn.nexus-brand{--btn-pad-x:.25rem}
  .nexus-header__row{padding-inline:1rem}
}

/* YOUR DECKS ON PHONES (2026-09-03). Two rows that were built for a wide
   pane. (1) The title row holds the heading, the deck count, Folders and
   New Deck on one flex line; below 640px it wraps and the two buttons take
   a line of their own, right-aligned under the heading. (2) In folder
   grouping, every folder header carries the path plus four 44px controls
   (public, subfolder, rename, delete); at 360px that left the name ~90px and
   "Competitive / cEDH Brews" broke onto three lines. The controls now sit in
   their own wrapper that wraps under the name on phones, so nothing is hidden
   -- every action stays one tap away -- and the name keeps the full width. */
.nexus-fold-head__name{min-inline-size:0;flex:1 1 auto;overflow-wrap:anywhere}
.nexus-fold-head__ctls{display:flex;align-items:center;gap:.5rem;margin-inline-start:auto;flex:none}
@media (max-width:639px){
  .nexus-yd-head{flex-wrap:wrap;row-gap:.75rem}
  .nexus-yd-head__actions{flex:1 0 100%;justify-content:flex-end}
  .nexus-fold-head{flex-wrap:wrap;row-gap:.5rem}
  .nexus-fold-head__ctls{flex-basis:100%;justify-content:flex-end}
}

/* ==========================================================================
   DRAG-AND-DROP INGESTION — added 2026-08-25.
   Every class has a real rule here, semantically named; nothing is composed
   at runtime, same contract as the button block above.
   Colours reuse the existing --btn-accent tokens so a dropzone cannot drift
   away from the button palette.
   ========================================================================== */

/* The manifest becomes a target only while a drag is actually over it. */
.nexus-dropzone{position:relative}
.nexus-dropzone--armed::after{
  content:'';position:absolute;inset:.5rem;z-index:40;pointer-events:none;
  border:2px dashed rgb(var(--nx-accent));border-radius:1rem;
  background:rgb(var(--nx-accent)/.06);
  box-shadow:inset 0 0 40px rgb(var(--nx-accent)/.12);
}
.nexus-dropzone__hint{
  position:absolute;top:50%;left:50%;translate:-50% -50%;z-index:41;
  pointer-events:none;padding:.5rem 1rem;border-radius:999px;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-accent));color:rgb(var(--nx-accent));
  font-size:.75rem;font-weight:700;letter-spacing:.04em;white-space:nowrap;
}

/* Source-gap advisory. Persistent (not a 4s toast) because it is teaching a
   gesture the user has to go and perform somewhere else. */
.nexus-advisory{
  position:fixed;bottom:1rem;right:1rem;z-index:60;inline-size:min(24rem,calc(100vw - 2rem));
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-slate-800));border-left:4px solid rgb(var(--nx-warning));
  border-radius:.75rem;padding:1rem;box-shadow:0 20px 40px rgba(0,0,0,.5);
  color:rgb(var(--nx-slate-200));font-size:.8125rem;line-height:1.5;
}
.nexus-advisory__title{
  display:flex;align-items:center;gap:.5rem;
  font-weight:700;font-size:.875rem;color:rgb(var(--nx-text));margin-block-end:.5rem;
}
.nexus-advisory__body{color:rgb(var(--nx-muted));margin-block-end:.75rem}
.nexus-advisory__body strong{color:rgb(var(--nx-slate-200))}
.nexus-advisory__steps{
  margin:.5rem 0 .75rem;padding:.5rem .75rem;border-radius:.5rem;
  background:#111827;border:1px solid rgb(var(--nx-slate-800));color:rgb(var(--nx-slate-300));font-size:.75rem;
}
.nexus-advisory__actions{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.nexus-advisory__dismiss{
  display:flex;align-items:center;gap:.375rem;margin-block-start:.625rem;
  color:rgb(var(--nx-slate-500));font-size:.6875rem;cursor:pointer;user-select:none;
}
@media (prefers-reduced-motion:reduce){
  .nexus-dropzone--armed::after{transition:none}
}

/* ==========================================================================
   FORM FIELDS — companion to .nexus-btn. Added 2026-08-25.
   Replaces 33 one-off field signatures (4 radii, 11 padding values,
   7 rendered heights on a single screen).

   RULE 1: every class here has a real rule, written at the end, semantic.
   RULE 3: unlayered and last, so it beats the ex-Tailwind utilities. Do NOT
           wrap in @layer.

   THE iOS FIX: any field with font-size < 16px makes Safari zoom the whole
   viewport on focus. --field-size is therefore forced to 1rem on coarse
   pointers. The alternative (maximum-scale=1 on the viewport meta) is an
   accessibility failure — it disables pinch-zoom for low-vision users — so
   the font-size floor is the only correct fix.

   LESSON FROM .nexus-btn: an unlayered block appended last silently outranks
   utilities it does not defer to. `display` and `resize` are guarded below.
   ========================================================================== */
.nexus-field{
  --field-min:2.25rem; --field-pad-y:.5rem; --field-pad-x:.75rem;
  --field-size:.875rem; --field-radius:.5rem; --field-accent:rgb(var(--nx-accent));
  min-block-size:var(--field-min);
  /* no field may exceed its container — prevents a select or input from being
     the thing that makes the whole page scroll sideways on a phone */
  max-inline-size:100%;
  padding-block:var(--field-pad-y);
  padding-inline:var(--field-pad-x);
  border:1px solid rgb(var(--nx-surface-hover));
  border-radius:var(--field-radius);
  background:rgb(var(--nx-base));
  color:rgb(var(--nx-text));
  font-family:inherit;
  font-size:var(--field-size);
  line-height:1.3;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.nexus-field::placeholder{color:rgb(var(--nx-muted));opacity:1}
.nexus-field:hover:not(:disabled):not(:focus){border-color:rgb(var(--nx-track))}
/* Border + glow is the affordance for ALL focus. The global :focus-visible
   outline still lands on top for keyboard users — deliberately not blanked. */
.nexus-field:focus{
  border-color:var(--field-accent);
  box-shadow:0 0 0 1px var(--field-accent),
             0 0 12px color-mix(in srgb,var(--field-accent) 28%,transparent);
}
.nexus-field:disabled{opacity:.45;cursor:not-allowed}

/* --- size --- */
.nexus-field--sm{--field-min:2rem;--field-pad-y:.25rem;--field-pad-x:.625rem;--field-size:.8125rem}
.nexus-field--md{--field-min:2.25rem;--field-pad-y:.5rem;--field-pad-x:.75rem;--field-size:.875rem}
.nexus-field--lg{--field-min:2.75rem;--field-pad-y:.75rem;--field-pad-x:1rem;--field-size:1rem}

/* --- tone: matches the button tones so a field and a button agree --- */
.nexus-field--violet {--field-accent:rgb(var(--nx-violet))}
.nexus-field--warning{--field-accent:rgb(var(--nx-warning))}
.nexus-field--success{--field-accent:rgb(var(--nx-success))}
.nexus-field--danger {--field-accent:rgb(var(--nx-error))}

/* --- leading/trailing icon wells: never fold these into the padding
       shorthand, or the icon sits on top of the text --- */
.nexus-field--icon-start{padding-inline-start:2.5rem}
.nexus-field--icon-end{padding-inline-end:2.5rem}

/* --- element specifics --- */
select.nexus-field{cursor:pointer}
textarea.nexus-field{line-height:1.5}

/* --- surface variant: fields sitting on an already-dark panel --- */
.nexus-field--raised{background:rgb(var(--nx-surface));border-color:rgb(var(--nx-surface-hover))}

/* --- checkboxes and radios: not fields, but they were 16x16 and WCAG 2.5.8
       wants 24px minimum. Sized here rather than left to chance. --- */
.nexus-check{
  inline-size:1.25rem; block-size:1.25rem;
  accent-color:rgb(var(--nx-accent));
  cursor:pointer;
  flex:none;
}

/* --- touch: 44px targets, and the 16px font floor that stops iOS zooming --- */
@media (pointer:coarse){
  .nexus-field,.nexus-field--sm,.nexus-field--md,.nexus-field--lg{
    --field-min:2.75rem;
    --field-size:1rem;
  }
  .nexus-check{inline-size:1.5rem;block-size:1.5rem}
}

/* --- guards: this block is LAST, so it would otherwise beat these utilities
       at equal specificity. Same class of bug that unhid 6 buttons. --- */
.nexus-field.hidden,.nexus-check.hidden{display:none}
.nexus-field.resize-none{resize:none}

/* --- quantity steppers (the -/N/+ group) ---------------------------------
   The input is transparent by design: the BORDER lives on the wrapping group,
   so this must not get field chrome. It still needs the 16px floor or iOS
   zooms the viewport when someone taps a card quantity. The +/- buttons are
   the pre-existing .nexus-step-btn (1.35rem = 21.6px), which fails the touch
   floor badly on a phone, so both get lifted together on coarse pointers. --- */
.nexus-stepper-input{
  background:transparent; border:0; color:rgb(var(--nx-text));
  font-family:inherit; text-align:center;
  inline-size:2.5rem; min-block-size:1.5rem;
  font-size:.875rem;
}
.nexus-stepper-input:focus{outline:none}
@media (pointer:coarse){
  .nexus-stepper-input{font-size:1rem; min-block-size:2.75rem; inline-size:3rem}
  .nexus-step-btn{width:2.75rem; height:2.75rem}
}


/* ==========================================================================
   CHIPS / BADGES — third companion to .nexus-btn and .nexus-field.
   Added 2026-08-25. Replaces 33 one-off signatures across 37 spans
   (4 radii, 9 padding values, 6 font sizes).

   LEGIBILITY FLOOR: the old set included text-[8px] and text-[9px]. Nothing
   here goes below 10px, and coarse pointers get a step up — a chip is read,
   not tapped, so it needs size for legibility rather than for a touch target.

   Chips are LABELS. A chip that is clickable should be a <button> with
   .nexus-btn--sm instead; several in the markup carry cursor-pointer on a
   <span>, which is a keyboard-accessibility gap logged in INBOX, not silently
   converted here.
   ========================================================================== */
.nexus-chip{
  --chip-accent:rgb(var(--nx-muted)); --chip-size:.6875rem; --chip-radius:.3rem;
  /* Split text states, as .nexus-btn has them: --chip-tint writes the tinted
     and ghost text, --chip-ink the solid text. Both default to the tone, so a
     tone that needs no split states nothing. */
  --chip-tint:var(--chip-accent); --chip-ink:rgb(var(--nx-accent-ink));
  display:inline-flex; align-items:center; gap:.3rem;
  padding:.15rem .5rem;
  border:1px solid color-mix(in srgb,var(--chip-accent) 40%,transparent);
  border-radius:var(--chip-radius);
  background:color-mix(in srgb,var(--chip-accent) 15%,transparent);
  /* Pulled 20% toward the page text, as .nexus-btn--tinted is. The raw tone
     failed AA in 117 of 432 tone x emphasis x theme x accent x ground cells
     (dark ghost violet 3.17, light tinted warning 3.80), measured by axe-core
     in a real page on 2026-09-10. */
  color:color-mix(in srgb,var(--chip-tint) 80%,rgb(var(--nx-text)));
  font-family:inherit; font-size:var(--chip-size); font-weight:700;
  line-height:1.4; white-space:nowrap;
}

/* --- tone: same six the buttons use, so a chip and a button finally agree --- */
.nexus-chip--blue   {--chip-accent:rgb(var(--nx-accent))}
/* violet and danger borrow the buttons' -lit text and white solid ink: their
   dark-theme fills are too deep for dark ink (3.45 and 4.19 before). */
.nexus-chip--violet {--chip-accent:rgb(var(--nx-violet));--chip-tint:rgb(var(--nx-violet-lit));--chip-ink:#fff}
.nexus-chip--danger {--chip-accent:rgb(var(--nx-error));--chip-tint:rgb(var(--nx-error-lit));--chip-ink:#fff}
.nexus-chip--success{--chip-accent:rgb(var(--nx-success))}
.nexus-chip--warning{--chip-accent:rgb(var(--nx-warning))}

/* --- emphasis --- */
.nexus-chip--solid{background:var(--chip-accent);color:var(--chip-ink);border-color:var(--chip-accent)}
.nexus-chip--ghost{background:transparent}

/* --- size / shape --- */
.nexus-chip--sm{--chip-size:.625rem;padding:.1rem .35rem}
.nexus-chip--pill{--chip-radius:999px;padding-inline:.6rem}

/* --- status dot: a 10px round indicator, not a chip --- */
.nexus-dot{
  display:inline-block; inline-size:.625rem; block-size:.625rem;
  border-radius:999px; background:var(--chip-accent,rgb(var(--nx-muted))); flex:none;
}
.nexus-dot--blue{--chip-accent:rgb(var(--nx-accent))}
.nexus-dot--violet{--chip-accent:rgb(var(--nx-violet))}
.nexus-dot--danger{--chip-accent:rgb(var(--nx-error))}
.nexus-dot--success{--chip-accent:rgb(var(--nx-success))}

@media (pointer:coarse){
  .nexus-chip{--chip-size:.75rem}
  .nexus-chip--sm{--chip-size:.6875rem}
}

/* --- guard: this block is LAST and sets display, same trap as .nexus-btn --- */
.nexus-chip.hidden,.nexus-dot.hidden{display:none}

/* --- floating deck action toolbar -----------------------------------------
   It is w-max, so on a phone it grows past the viewport and clips its own
   primary action ("Save Deck Version"). Scroll inside itself instead of
   letting the page clip it. Children must not shrink or they squash. --- */
.nexus-deck-toolbar{
  max-inline-size:calc(100vw - 1rem);
  overflow-x:auto;
  overscroll-behavior-x:contain;
  scrollbar-width:none;
  /* justify-center on a scroll container makes the start unreachable: the
     content centres and overflows BOTH edges. Start-align so the primary
     action is what you see first and the rest is swipeable. */
  justify-content:flex-start;
}
.nexus-deck-toolbar::-webkit-scrollbar{display:none}
.nexus-deck-toolbar > *{flex:none}

/* --- row controls & touch reveal ------------------------------------------
   The folder-row controls (Rename / New subfolder / Make public / Delete)
   previously used `hidden group-hover/frow:flex`. No rule for that class was
   ever generated — there is no build step — so they were display:none on
   EVERY device. Verified 2026-08-25 by real mouse hover (stayed none) and a
   real CDP touch tap (stayed none). Opacity is used instead of display so the
   row height never jumps, and :focus-within makes them keyboard reachable. --- */
.nexus-row-ctl{opacity:0}
.group\/frow:hover .nexus-row-ctl,
.group\/frow:focus-within .nexus-row-ctl,
.nexus-row-ctl:focus-visible{opacity:1}

@media (pointer:coarse){
  /* hover does not exist on touch, so anything gated behind it is unreachable */
  .nexus-row-ctl,.nexus-touch-reveal{opacity:1}
  :where(button,a)[class*="group-hover:opacity-100"]{opacity:1}
}

/* --- interactive list rows -------------------------------------------------
   .dropdown-item is the card-name autocomplete row — the most-used control in
   deckbuilding — and had NO rule of its own, only utilities in its template.
   It measured 41px, three under the touch floor. Arrow-key navigation already
   exists in the JS; this gives the rows a real minimum size and a focus state. */
.dropdown-item{min-block-size:2.25rem;display:flex;align-items:center}
.dropdown-item:focus-visible{outline:2px solid rgb(var(--nx-accent));outline-offset:-2px}
@media (pointer:coarse){.dropdown-item{min-block-size:2.75rem}}

/* --- clickable non-buttons -------------------------------------------------
   21 elements carry an inline onclick but are <div>/<span>: they take no
   keyboard focus and fire no Enter/Space, so they are mouse-only. The script
   at the end of the document stamps tabindex/role and bridges the keys; this
   gives them the same visible focus treatment as every real control. --- */
[data-nexus-clickable]:focus-visible{outline:2px solid rgb(var(--nx-accent));outline-offset:2px;border-radius:4px}

/* --- full-screen modal shells ----------------------------------------------
   `flex ... justify-center` on an overlay centres content that is TALLER than
   the viewport so it overflows both edges, and with no overflow-y there is no
   way to scroll back up to it. Session Zero opened on "Zero" with "Session"
   clipped above the fold. Auto margins centre identically when there is room
   but stay scrollable to the true start when there is not — the same trap the
   deck toolbar hit horizontally. Top padding clears the fixed close control. */
.nexus-modal-shell{
  overflow-y:auto;
  overscroll-behavior:contain;
  justify-content:flex-start;
  padding-block-start:4.5rem;
}
.nexus-modal-shell > *{margin-block:auto}

/* --- deck studio control row -----------------------------------------------
   VIEW / GROUP / SORT are three label+select pairs. Letting them wrap put each
   pair on its own line: 156px of a 292px sticky block, on top of an 88px nav —
   45% of a phone screen was fixed chrome before a single card showed. Stacking
   each label над its select turns three rows into three columns in one row.
   The sticky behaviour itself is deliberate (see the #manifest-view note) and
   is left alone. --- */
@media (max-width:640px){
  .nexus-studio-controls{gap:.5rem}
  .nexus-studio-controls > div{
    flex-direction:column; align-items:stretch; gap:.2rem;
    flex:1 1 0; min-inline-size:0;
  }
  .nexus-studio-controls > div > span{font-size:.625rem;text-align:center;letter-spacing:.04em}
  .nexus-studio-controls .nexus-field{inline-size:100%}
  /* Group Same Cards shared the row with the three pairs and, being content-
     sized, took ~150px of 312: the selects were left 43px each and showed
     only their arrows. On phones the button takes its own line below. */
  .nexus-studio-controls > .nexus-btn{flex:0 0 100%}
}

/* --- deck list rows --------------------------------------------------------
   The card NAME is the most important datum in a deck list and was losing the
   width fight: 115px for the name against a 204px shrink-0 metrics block on a
   390px screen, so names read "Talisman of Domi…". Tightening the gaps between
   mana/price/set on narrow screens returns the space to the name without
   dropping any information. --- */
@media (max-width:640px){
  .nexus-row-meta{margin-inline-start:.25rem}
  .nexus-row-meta > * + *{margin-inline-start:.375rem}
  /* Tightening the gaps bought only a character or two, because revealing the
     row action control on touch costs 44px per row. On a phone the card name
     matters more than a fixed row height, so let it wrap to two lines instead
     of being clipped to "Talisman of Domi…". */
  [id^="row-name"]{
    white-space:normal;
    display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
    overflow:hidden;line-height:1.25;
  }
}







/* --- active taxonomy chip row ----------------------------------------------
   The row of applied filters, directly under the hub filter bar. It used to be
   an inline group inside that bar; at three chips it was winning the width
   fight against the search box on a laptop and forcing it to wrap.

   `min-inline-size:0` on the row is what lets a long chip label ellipsis
   instead of pushing the row wider than its container. --- */
.nexus-chip-row{
  display:flex;flex-wrap:wrap;align-items:center;gap:.375rem;
  min-inline-size:0;margin-block-end:1rem;
}
.nexus-chip-row.hidden{display:none}
.nexus-chip-row-label{
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;line-height:1rem;letter-spacing:.1em;
  text-transform:uppercase;font-weight:700;color:rgb(var(--nx-muted));
  margin-inline-end:.125rem;
}
/* The vocabulary a chip came from. Present because it is the ONLY thing that
   separates the Archetype "Mill" from the Mechanic "Mill", and those are
   different filters over different columns. Quiet, but never hidden. */
.nexus-chip-kind{
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;line-height:1rem;letter-spacing:.04em;
  opacity:.6;margin-inline-start:.25rem;
}

/* --- guided search flyout ---------------------------------------------------
   The filter half of the hub search dropdown. Cards were always in this panel;
   these rules are for the rows ABOVE them, which offer taxonomy filters in
   plain English and show the syntax each one emits.

   The panel is ONE list on purpose (mockups/search-flyout-mockup.html, option
   A). Group headers are deliberately NOT .dropdown-item, which is what makes
   the existing arrow-key walker skip them for free — the "headers are skipped"
   rule is enforced by that omission, not by a special case in the keyboard
   handler. If a header ever needs to be focusable, the walker needs changing
   too.

   Highlight: highlightItem() puts .bg-nexus-violet on the row, and the row's
   children carry their own muted colours which would otherwise stay muted and
   unreadable on violet. The descendant rules below re-colour them; they are
   scoped to .nexus-flyout-row so no other dropdown is affected. --- */
/* The panel is anchored to the search input, which is one control in a crowded
   filter bar and only ~260px wide there. At that width a filter row cannot show
   a name, a kind and a syntax caption at once -- the first render crushed every
   name to "Sac...", "S...", "F...". The panel is absolutely positioned, so it is
   free to be wider than the box it hangs off; it just must never exceed the
   viewport. */
.nexus-flyout-panel{
  max-block-size:26rem;
  inline-size:max(100%, 30rem);
  max-inline-size:min(40rem, calc(100vw - 2rem));
}
/* The panel carries the ex-Tailwind `divide-y`, which puts a border-top on
   every child after the first. Card rows already draw their own border-b, so
   between two flyout rows that would stack two lines in two different colours.
   Matched specificity (0,3,0) against `.divide-y>:not([hidden])~:not([hidden])`
   and placed later in source, so these win without touching the card rows. */
.nexus-flyout-panel > .nexus-flyout-group:not([hidden]),
.nexus-flyout-panel > .nexus-flyout-row:not([hidden]){border-block-start:0}

.nexus-flyout-group{
  padding:.5rem .75rem .25rem;
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;line-height:1rem;letter-spacing:.1em;
  text-transform:uppercase;font-weight:700;
  color:rgb(var(--nx-muted));background:rgb(var(--nx-base));
  position:sticky;top:0;z-index:1;
}

.nexus-flyout-row{
  display:block;
  padding:.5rem .75rem;cursor:pointer;
  border-block-end:1px solid rgb(var(--nx-surface-hover)/.4);
}
.nexus-flyout-row:last-child{border-block-end:0}
.nexus-flyout-row:hover{background:rgb(var(--nx-violet));color:rgb(var(--nx-base))}

.nexus-flyout-title{display:flex;align-items:baseline;gap:.5rem;min-inline-size:0}
/* The NAME is the datum that matters and must win every width fight. Both it
   and the syntax caption may shrink, but the caption yields 8x faster, so a
   narrow panel eats the caption rather than the name. */
.nexus-flyout-name{
  flex:0 1 auto;min-inline-size:0;
  font-weight:700;font-size:.875rem;line-height:1.25rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.nexus-flyout-kind{
  flex:0 0 auto;
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;line-height:1rem;letter-spacing:.05em;
  text-transform:uppercase;color:rgb(var(--nx-muted));
}
/* Two lines, then clamp. A one-line clamp cuts most descriptions mid-clause
   and reads as truncation noise; three makes the row taller than a card. */
.nexus-flyout-desc{
  margin-block-start:.125rem;
  font-size:.75rem;line-height:1rem;color:rgb(var(--nx-muted));
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
  overflow:hidden;
}
/* The teaching half: the syntax this row would emit if typed by hand. Greyed
   and right-aligned so it reads as a caption, not an action. */
.nexus-flyout-syntax{
  flex:0 8 auto;min-inline-size:0;
  margin-inline-start:auto;padding-inline-start:.5rem;
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;line-height:1rem;
  color:rgb(var(--nx-muted));opacity:.75;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* Readable on the violet highlight, whether it arrived by hover or by arrow
   key. Without these the description and the syntax caption stay #94a3b8 on
   #7c3aed, which is under 2:1 contrast. */
.nexus-flyout-row:hover .nexus-flyout-kind,
.nexus-flyout-row:hover .nexus-flyout-desc,
.nexus-flyout-row:hover .nexus-flyout-count,
.nexus-flyout-row:hover .nexus-flyout-syntax,
.nexus-flyout-row.bg-nexus-violet .nexus-flyout-kind,
.nexus-flyout-row.bg-nexus-violet .nexus-flyout-desc,
.nexus-flyout-row.bg-nexus-violet .nexus-flyout-count,
.nexus-flyout-row.bg-nexus-violet .nexus-flyout-syntax{
  color:rgb(var(--nx-base));opacity:.85;
}

/* How many cards a filter actually matches, shown on every row and tile
   rather than hiding the empty ones (Chad 2026-08-27: we warn, we do not
   prohibit). Amber, not red -- an empty filter is a dead end, not a mistake
   the user made. Both --empty rules sit AFTER the hover block above so the
   warning colour survives the highlight; without that an empty row would go
   near-black on violet and read as ordinary. */
.nexus-flyout-count{
  flex:0 0 auto;
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;line-height:1rem;color:rgb(var(--nx-muted));
}
.nexus-tax-count{
  margin-block-start:.25rem;
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;line-height:1rem;color:rgb(var(--nx-slate-300));
}
.nexus-flyout-count--empty,
.nexus-flyout-row:hover .nexus-flyout-count--empty,
.nexus-flyout-row.bg-nexus-violet .nexus-flyout-count--empty,
.nexus-tax-count--empty{
  color:#f59e0b;opacity:1;
}

/* === 2026-08-26 — Deck intelligence relaunch. New classes, so rules live here
   per THE RULES #1. Colours are the nexus tokens, not new hex. State modifiers
   are fixed class names selected from a literal map in the shell -- never
   composed from data, per THE RULES #2. === */
.nexus-grade{display:flex;flex-direction:column;gap:.4rem;padding:.85rem 1rem;border-radius:15px;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));border-left-width:3px}
.nexus-grade__head{display:flex;align-items:center;justify-content:space-between;gap:.75rem}
.nexus-grade__verdict{font-size:.6875rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase}
.nexus-grade__delta{font-size:.6875rem;font-weight:700;color:rgb(var(--nx-muted))}
.nexus-grade__headline{font-size:.75rem;line-height:1.55;color:rgb(var(--nx-text));margin:0}
/* How the deck wins, in the engine's own words, above the working. Turns come
   first and the win condition is named; the probability behind it is used by
   the engine and never shown (Chad 2026-09-05). */
.nexus-grade__win{font-size:.75rem;line-height:1.55;font-weight:700;color:rgb(var(--nx-text));margin:.35rem 0 0}
/* The two clocks in one line, and the levers that move them (engine-computed
   before/after sentences; the shell renders, it does not decide). */
.nexus-grade__clock{font-size:.6875rem;line-height:1.5;color:rgb(var(--nx-muted));margin:.25rem 0 0}
.nexus-grade__levers{margin-top:.5rem}
.nexus-grade__levers-title{font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:rgb(var(--nx-muted));margin:0 0 .25rem}
.nexus-grade__levers-list{list-style:none;margin:0;padding:0;display:grid;gap:.25rem}
.nexus-grade__lever{font-size:.75rem;line-height:1.5;color:rgb(var(--nx-text));padding-left:.75rem;position:relative}
.nexus-grade__lever::before{content:"\2022";position:absolute;left:0;color:rgb(var(--nx-muted))}
.nexus-grade--on-target{border-left-color:rgb(var(--nx-success))}
.nexus-grade--on-target .nexus-grade__verdict{color:rgb(var(--nx-success))}
.nexus-grade--under{border-left-color:rgb(var(--nx-accent))}
.nexus-grade--under .nexus-grade__verdict{color:rgb(var(--nx-accent))}
.nexus-grade--overload{border-left-color:rgb(var(--nx-error))}
.nexus-grade--overload .nexus-grade__verdict{color:rgb(var(--nx-error))}

.nexus-routes{display:flex;flex-direction:column;gap:.7rem;padding:1rem;border-radius:15px;background:rgb(var(--nx-surface))}
.nexus-routes__head{display:flex;align-items:baseline;justify-content:space-between;gap:.5rem}
.nexus-routes__title{font-family:Orbitron,ui-sans-serif,system-ui,sans-serif;font-size:.8125rem;font-weight:800;
  letter-spacing:.1em;text-transform:uppercase;color:rgb(var(--nx-text))}
.nexus-routes__horizon{font-size:.625rem;font-weight:700;letter-spacing:.06em;color:rgb(var(--nx-muted))}
.nexus-routes__list{display:flex;flex-direction:column;gap:.6rem}
.nexus-route{display:flex;flex-direction:column;gap:.3rem}
.nexus-route__top{display:flex;align-items:center;justify-content:space-between;gap:.5rem;font-size:.75rem}
.nexus-route__name{font-weight:700;color:rgb(var(--nx-text))}
.nexus-route__tag{font-size:.5625rem;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  padding:.1rem .35rem;border-radius:4px;margin-left:.4rem;vertical-align:middle}
.nexus-route__tag--primary{background:rgb(var(--nx-violet));color:rgb(var(--nx-text))}
.nexus-route__tag--backup{background:rgb(var(--nx-track));color:rgb(var(--nx-muted))}
.nexus-route__pct{font-weight:700;color:rgb(var(--nx-muted));font-variant-numeric:tabular-nums}
.nexus-route__track{width:100%;height:.375rem;border-radius:9999px;background:rgb(var(--nx-track));overflow:hidden}
.nexus-route__fill{height:100%;border-radius:9999px;transition:width .5s ease}
.nexus-route__fill--primary{background:rgb(var(--nx-violet))}
.nexus-route__fill--backup{background:rgb(var(--nx-accent))}
.nexus-route__fill--unscored{background:rgb(var(--nx-slate-700))}
.nexus-route__detail{font-size:.625rem;color:rgb(var(--nx-muted))}
.nexus-route--unscored .nexus-route__name{color:rgb(var(--nx-muted))}
.nexus-routes__note{font-size:.6875rem;line-height:1.5;margin:0;padding:.6rem .75rem;border-radius:10px;
  background:rgb(var(--nx-surface-alt));color:rgb(var(--nx-text));border-left:3px solid rgb(var(--nx-warning))}

.nexus-headroom{display:flex;flex-direction:column;gap:.6rem;padding:1rem;border-radius:15px;background:rgb(var(--nx-surface))}
.nexus-headroom__title{font-family:Orbitron,ui-sans-serif,system-ui,sans-serif;font-size:.8125rem;font-weight:800;
  letter-spacing:.1em;text-transform:uppercase;color:rgb(var(--nx-text))}
.nexus-headroom__list{display:flex;flex-direction:column;gap:.5rem}

/* --- guard: .nexus-grade, .nexus-routes and .nexus-headroom all set display,
       so `.hidden` lost to them at equal specificity and the three JS calls that
       hide these sections (renderBracketGrade, renderWinRoutes, renderHeadroom)
       silently left an empty bordered box with its heading behind. Measured
       2026-08-27 on a deck with no bracket chosen: #nexus-routes carried class
       "nexus-routes hidden" and still computed display:flex at 62.69px tall.
       Same trap the stylesheet already guards for .nexus-btn, .nexus-field,
       .nexus-chip, .nexus-swap and .nexus-panel[hidden]. --- */
.nexus-grade.hidden,.nexus-routes.hidden,.nexus-headroom.hidden{display:none}
.nexus-lever{display:flex;gap:.55rem;align-items:flex-start;font-size:.6875rem;line-height:1.5}
.nexus-lever__dot{flex:0 0 auto;width:.5rem;height:.5rem;border-radius:9999px;margin-top:.35rem}
.nexus-lever__body{display:flex;flex-direction:column;gap:.15rem;min-width:0}
.nexus-lever__label{font-weight:700;color:rgb(var(--nx-text))}
.nexus-lever__msg{color:rgb(var(--nx-muted))}
.nexus-lever__advisory{color:rgb(var(--nx-warning));font-weight:600}
.nexus-lever--unused .nexus-lever__dot{background:rgb(var(--nx-accent))}
.nexus-lever--partial .nexus-lever__dot{background:rgb(var(--nx-accent))}
.nexus-lever--open .nexus-lever__dot{background:rgb(var(--nx-accent))}
.nexus-lever--full .nexus-lever__dot{background:rgb(var(--nx-success))}
.nexus-lever--locked .nexus-lever__dot{background:rgb(var(--nx-track))}
.nexus-lever--advisory .nexus-lever__dot{background:rgb(var(--nx-warning))}
.nexus-lever--over .nexus-lever__dot{background:rgb(var(--nx-error))}
.nexus-lever--over .nexus-lever__label{color:rgb(var(--nx-error))}

/* === 2026-08-26 — THE INTELLIGENCE RAIL ====================================
   Four engines used to stack vertically down a 6,449px page: Manabase Grader,
   Synergy Upgrades and Combo Finishers only existed if you scrolled almost six
   screens, which on a phone is closer to fifteen. The rail collapses them into
   one always-reachable strip with a status dot each, and a drawer that shows
   one panel at a time.

   It renders values the engines already computed and cached in NEXUS_STATE.
   It fetches nothing and decides nothing.

   Mobile-first: the base rules ARE the phone layout (bottom tab bar + sheet).
   The >=1024px block turns it back into the right-edge rail + side drawer.
   1024px, not the mockup's 860: below that the deck page has already collapsed
   out of its three-column layout, and a 376px drawer would be taking 43% of the
   viewport. A sheet you can drag away is the better answer at that size.

   New classes, so their rules live here per THE RULES #1. Every state modifier
   is a fixed class name chosen from a literal map in the shell, never composed
   from data (THE RULES #2). The tabs are .nexus-btn -- .nexus-rail-tab only
   re-points the component's own --btn-* custom properties, which is the
   sanctioned way to fit a button to a slot; it adds no size, emphasis or tone.
   ========================================================================== */
:root{--nexus-rail-w:3.75rem;--nexus-drawer-w:23.5rem;--nexus-rail-bar-h:3.75rem}

.nexus-rail-root{
  position:fixed;z-index:120;inset-inline:0;
  display:flex;flex-direction:column;pointer-events:none;
  /* The deck page overflows horizontally on a phone for reasons that predate
     this rail: measured 445px of content in a 390px viewport on deck fb41f8da.
     Chrome answers that by stretching the initial containing block in BOTH axes
     (445x964 against a visible 390x844), and a fixed element resolves inset and
     percentages against that block -- so a plain inset-inline:0 / inset-block-end:0
     bar grows to 445 wide and sits 120px BELOW the fold, unreachable.
     vw/dvh track the visible layout viewport and do not stretch, so these two
     lines pin the bar to what the user can actually see, and both collapse to
     the obvious values (100vw = 100%, bottom = 0) on a page that does not
     overflow. The overflow itself is captured in INBOX.md; it is not this
     rail's bug to fix. */
  max-inline-size:100vw;
  inset-block-end:calc(100% - 100dvh);
}
.nexus-rail-root > *{pointer-events:auto}

/* --- the rail: a bottom tab bar on a phone -------------------------------- */
.nexus-rail{
  order:2;display:flex;inline-size:100%;gap:.25rem;flex:none;
  padding:.25rem .25rem calc(.25rem + env(safe-area-inset-bottom,0px));
  background:rgb(var(--nx-base));border-block-start:1px solid rgb(var(--nx-surface-hover));
}
.nexus-rail__spacer,.nexus-rail__rule{display:none}
.nexus-rail-tab{
  position:relative;flex:1 1 0;flex-direction:column;gap:.1rem;
  --btn-pad-x:.15rem;--btn-pad-y:.3rem;--btn-min:2.75rem;--btn-radius:.625rem;
}
.nexus-rail-tab__glyph{font-size:.9375rem;line-height:1}
.nexus-rail-tab__label{
  font-size:.625rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
}
.nexus-rail-tab__dot{
  position:absolute;inset-block-start:.25rem;inset-inline-end:.35rem;
  inline-size:.5rem;block-size:.5rem;border-radius:9999px;border:2px solid rgb(var(--nx-base));
}
.nexus-rail-tab__dot--red{background:rgb(var(--nx-error))}
.nexus-rail-tab__dot--amber{background:rgb(var(--nx-warning))}
.nexus-rail-tab__dot--green{background:rgb(var(--nx-success))}
.nexus-rail-tab__dot--none{display:none}

/* --- 2026-08-29 — THE SOON GATE ------------------------------------------
   Chad's call while the rail's engines are being debugged: the LIVE site shows
   one "Soon" strip where the five tabs are, and never opens the drawer. Nothing
   is deleted. nexusRailPaintSoon() puts data-soon on this nav when the page is
   not being served from 127.0.0.1, and these rules swap what is visible; on the
   dev host the attribute is never set and the rail behaves exactly as built.
   The strip keeps the bar's height, so #manifest-view[data-rail] padding and the
   floating toolbar offset stay correct with no other change. */
.nexus-rail-soon{display:none}
/* 2026-09-11: the bracket estimate outside the rail (the deck hero's
   "Building for / Deck reads as" pair, the Analysis bracket bars, the Community
   Hub bracket filter) follows the same rule. Base.astro stamps data-intel-soon
   on <html> off the dev host. */
html[data-intel-soon] [data-intel-soon]{display:none !important}
.nexus-rail[data-soon] .nexus-rail-tab,
.nexus-rail[data-soon] .nexus-rail__rule{display:none}
.nexus-rail[data-soon] .nexus-rail-soon{
  display:flex;flex:1 1 0;align-items:center;justify-content:center;gap:.5rem;
  min-block-size:2.75rem;
}
.nexus-rail-soon__glyph{font-size:.9375rem;line-height:1;color:rgb(var(--nx-muted))}
.nexus-rail-soon__label{font-size:.75rem;font-weight:600;color:rgb(var(--nx-text))}
.nexus-rail-soon__tag{
  font-size:.625rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  padding:.15rem .45rem;border-radius:9999px;
  color:rgb(var(--nx-warning));background:rgb(var(--nx-warning)/.12);border:1px solid rgb(var(--nx-warning)/.35);
}

/* --- the drawer: a bottom sheet on a phone -------------------------------- */
.nexus-drawer{
  order:1;display:flex;flex-direction:column;
  inline-size:100%;block-size:var(--nexus-sheet-h,55vh);max-block-size:92vh;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));border-block-end:0;
  border-start-start-radius:1rem;border-start-end-radius:1rem;
  box-shadow:0 -12px 40px rgba(0,0,0,.55);
}
/* .nexus-drawer sets display, and the reset's [hidden] rule is written with
   :where() so it carries no specificity. Restate it, same trap as .nexus-btn. */
.nexus-drawer[hidden]{display:none}

/* Half sheet by default so the decklist stays visible behind it; this button
   snaps it to full and back. A real <button>, so it works from the keyboard,
   and a pointer drag on it does the same job continuously. */
.nexus-drawer__grab{
  --btn-min:1.75rem;--btn-pad-y:.4rem;--btn-pad-x:0;
  inline-size:100%;flex:none;touch-action:none;
}
.nexus-drawer__grab::before{
  content:"";inline-size:2.125rem;block-size:.25rem;border-radius:9999px;background:rgb(var(--nx-track));
}
.nexus-drawer__head{
  display:flex;align-items:center;gap:.55rem;flex:none;
  padding:.75rem 1rem;border-block-end:1px solid rgb(var(--nx-surface-hover));
}
.nexus-drawer__icon{color:rgb(var(--nx-accent));font-size:.875rem;flex:none}
.nexus-drawer__title{
  flex:1;min-inline-size:0;
  font-family:Orbitron,ui-sans-serif,system-ui,sans-serif;
  font-size:.8125rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:rgb(var(--nx-text));
}
.nexus-drawer__pill{
  flex:none;font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;font-weight:700;letter-spacing:.04em;white-space:nowrap;
  padding:.15rem .4rem;border-radius:5px;background:rgb(var(--nx-surface-hover));color:rgb(var(--nx-muted));
}
.nexus-drawer__pill--blue{background:rgb(var(--nx-accent)/.12);color:rgb(var(--nx-accent))}
.nexus-drawer__pill--red{background:rgb(var(--nx-error)/.14);color:rgb(var(--nx-error))}
.nexus-drawer__pill--amber{background:rgb(var(--nx-warning)/.16);color:rgb(var(--nx-warning))}
.nexus-drawer__pill--green{background:rgb(var(--nx-success)/.16);color:rgb(var(--nx-success))}
.nexus-drawer__pill--muted{background:rgb(var(--nx-surface-hover));color:rgb(var(--nx-muted))}
.nexus-drawer__body{
  flex:1;min-block-size:0;overflow-y:auto;overscroll-behavior:contain;
  padding:1rem;display:flex;flex-direction:column;gap:1rem;
}
.nexus-panel{display:flex;flex-direction:column;gap:.85rem}
.nexus-panel[hidden]{display:none}

/* --- shared panel furniture ----------------------------------------------- */
.nexus-rail-note{
  font-size:.6875rem;line-height:1.55;margin:0;padding:.6rem .75rem;border-radius:10px;
  background:rgb(var(--nx-surface-alt));color:rgb(var(--nx-text));border-inline-start:3px solid rgb(var(--nx-accent));
}
.nexus-rail-note--warn{border-inline-start-color:rgb(var(--nx-warning))}
.nexus-rail-note--bad{border-inline-start-color:rgb(var(--nx-error))}
.nexus-rail-note--good{border-inline-start-color:rgb(var(--nx-success))}
.nexus-rail-note b{font-weight:700}

.nexus-rail-stats{display:grid;grid-template-columns:1fr 1fr;gap:.5rem}
.nexus-rail-stat{
  display:flex;flex-direction:column;gap:.1rem;
  padding:.6rem .7rem;border-radius:10px;background:rgb(var(--nx-surface-alt));border:1px solid rgb(var(--nx-surface-hover));
}
.nexus-rail-stat__k{
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;letter-spacing:.08em;text-transform:uppercase;color:rgb(var(--nx-muted));
}
.nexus-rail-stat__v{
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:1.125rem;font-weight:700;color:rgb(var(--nx-text));font-variant-numeric:tabular-nums;
}
.nexus-rail-stat__s{font-size:.625rem;color:rgb(var(--nx-muted))}
.nexus-rail-stat--bad .nexus-rail-stat__v{color:rgb(var(--nx-error))}
.nexus-rail-stat--warn .nexus-rail-stat__v{color:rgb(var(--nx-warning))}
.nexus-rail-stat--good .nexus-rail-stat__v{color:rgb(var(--nx-success))}

.nexus-rail-list{display:flex;flex-direction:column;gap:.5rem}
.nexus-rail-item{
  display:flex;flex-direction:column;gap:.15rem;
  padding:.6rem .7rem;border-radius:10px;background:rgb(var(--nx-surface-alt));border:1px solid rgb(var(--nx-surface-hover));
}
.nexus-rail-item__top{display:flex;align-items:baseline;justify-content:space-between;gap:.5rem}
.nexus-rail-item__title{
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:rgb(var(--nx-accent));
}
.nexus-rail-item__title--warn{color:rgb(var(--nx-warning))}
.nexus-rail-item__title--good{color:rgb(var(--nx-success))}
.nexus-rail-item__meta{
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;color:rgb(var(--nx-muted));flex:none;font-variant-numeric:tabular-nums;
}
.nexus-rail-item__sub{font-size:.75rem;line-height:1.45;color:rgb(var(--nx-text))}
.nexus-rail-item__sub--muted{color:rgb(var(--nx-muted))}
.nexus-rail-empty{
  font-size:.6875rem;line-height:1.5;color:rgb(var(--nx-muted));margin:0;
  padding:.9rem .75rem;border-radius:10px;border:1px dashed rgb(var(--nx-surface-hover));background:rgb(var(--nx-surface-alt));text-align:center;
}
.nexus-rail-action{inline-size:100%}

/* --- the dial: win turn at the centre, the four scores as rings ----------- */
.nexus-gauge{
  display:flex;align-items:center;gap:1rem;
  padding:.85rem;border-radius:10px;background:rgb(var(--nx-surface-alt));border:1px solid rgb(var(--nx-surface-hover));
}
.nexus-gauge__ring{position:relative;inline-size:6rem;block-size:6rem;flex:none}
.nexus-gauge__label{
  position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;
}
.nexus-gauge__cap{
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.5625rem;letter-spacing:.14em;color:rgb(var(--nx-muted));
}
.nexus-gauge__turn{
  font-family:Orbitron,ui-sans-serif,system-ui,sans-serif;
  font-size:1.5rem;font-weight:800;line-height:1;color:rgb(var(--nx-text));
}
.nexus-legend{display:flex;flex-direction:column;gap:.4rem;flex:1;min-inline-size:0}
.nexus-legend__row{display:flex;align-items:center;gap:.5rem;font-size:.75rem}
.nexus-legend__sw{inline-size:.5rem;block-size:.5rem;border-radius:9999px;flex:none}
.nexus-legend__sw--lethality{background:rgb(var(--nx-error))}
.nexus-legend__sw--speed{background:rgb(var(--nx-accent))}
.nexus-legend__sw--consistency{background:rgb(var(--nx-violet))}
.nexus-legend__sw--interaction{background:rgb(var(--nx-success))}
.nexus-legend__name{flex:1;color:rgb(var(--nx-muted));min-inline-size:0}
.nexus-legend__val{
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-weight:700;color:rgb(var(--nx-text));font-variant-numeric:tabular-nums;
}

/* Rule labels the deck actually trips. Warn, never restrict: this is a list of
   what the table would need to know, not a list of things to remove. */
.nexus-rail-flag{
  display:flex;gap:.5rem;align-items:flex-start;
  font-size:.6875rem;line-height:1.5;color:rgb(var(--nx-text));
}
.nexus-rail-flag__mark{color:rgb(var(--nx-warning));flex:none;font-weight:700}
.nexus-rail-flag--over .nexus-rail-flag__mark{color:rgb(var(--nx-error))}

/* --- the fixed rail has to be given its width, or the decklist slides under
       it. Phone reserves the tab bar's height instead. ---------------------- */
#manifest-view[data-rail]{
  padding-block-end:calc(var(--nexus-rail-bar-h) + env(safe-area-inset-bottom,0px));
}
/* The floating deck toolbar is bottom:1.5rem and would sit under the tab bar. */
#manifest-view[data-rail] #floating-action-bar{
  bottom:calc(1.5rem + var(--nexus-rail-bar-h));
}

@media (min-width:1024px){
  /* Start below the sticky site header, and below the read-only banner when one
     exists -- --nexus-banner-h is set on #manifest-view by
     applyReadOnlyPresentation and is 0px otherwise, the same offset the deck
     toolbar and the two side rails already use. Without this the rail sits ON
     the header, which is the one strip of chrome that must always stay on top. */
  .nexus-rail-root{
    inset-block:calc(70px + var(--nexus-banner-h,0px)) 0;
    inset-inline:auto 0;flex-direction:row;align-items:stretch;
  }
  .nexus-rail{
    order:2;flex-direction:column;align-items:center;
    inline-size:var(--nexus-rail-w);block-size:100%;gap:.375rem;
    padding:.75rem 0;border-block-start:0;border-inline-start:1px solid rgb(var(--nx-surface-hover));
  }
  .nexus-rail__spacer{display:block;flex:1}
  .nexus-rail__rule{display:block;flex:none;inline-size:1.625rem;block-size:1px;background:rgb(var(--nx-surface-hover))}
  .nexus-rail-tab{flex:none;inline-size:2.625rem;--btn-min:2.625rem;--btn-pad-x:0;--btn-pad-y:0}
  .nexus-rail-tab__glyph{font-size:1.0625rem}
  .nexus-rail-tab__label{display:none}
  /* Vertical strip: the word "Soon" alone fits 2.625rem; the noun does not. */
  .nexus-rail[data-soon] .nexus-rail-soon{
    flex:none;flex-direction:column;gap:.25rem;inline-size:2.625rem;min-block-size:auto;
  }
  .nexus-rail-soon__glyph{font-size:1.0625rem}
  .nexus-rail-soon__label{display:none}
  .nexus-rail-soon__tag{font-size:.5rem;letter-spacing:.04em;padding:.1rem .25rem}
  .nexus-drawer{
    order:1;inline-size:var(--nexus-drawer-w);block-size:100%;max-block-size:none;
    border-radius:0;border-block:0;border-inline-end:0;border-inline-start:1px solid rgb(var(--nx-surface-hover));
    box-shadow:-16px 0 40px rgba(0,0,0,.45);
  }
  .nexus-drawer__grab{display:none}
  #manifest-view[data-rail]{
    padding-block-end:0;padding-inline-end:var(--nexus-rail-w);
    transition:padding-inline-end .2s ease;
  }
  #manifest-view[data-rail] #floating-action-bar{bottom:1.5rem}
  #manifest-view[data-rail="intel"],
  #manifest-view[data-rail="mana"],
  #manifest-view[data-rail="syn"],
  #manifest-view[data-rail="combo"],
  #manifest-view[data-rail="rules"]{
    padding-inline-end:calc(var(--nexus-rail-w) + var(--nexus-drawer-w));
  }
}
@media (prefers-reduced-motion:reduce){
  #manifest-view[data-rail]{transition:none}
}

/* === 2026-08-27 — Rail, part two: the retired panels move in ================
   The inline Deck Intelligence sidebar, Manabase Grader, Synergy Upgrades and
   Combo Finishers panels were removed from the page today. Their content did
   not disappear -- the sidebar's own nodes were MOVED into the drawer, so every
   id the render functions target is the same node it always was, and the three
   card panels got the half of the old design that was worth keeping: the art.

   The drawer is 376px, so a suggestion is shown one at a time and paged, rather
   than laid out in a strip that would need its own horizontal scroll.
   ========================================================================== */

/* Target Power leads the Intelligence panel. Every verdict, headroom lever and
   win-route horizon under it is computed against this one choice, and it used
   to be a small select in the corner of a panel. */
.nexus-target{
  display:flex;align-items:center;justify-content:space-between;gap:.75rem;
  padding:.7rem .85rem;border-radius:12px;
  background:rgb(var(--nx-surface-alt));border:1px solid rgb(var(--nx-track));border-inline-start:3px solid rgb(var(--nx-accent));
}
.nexus-target__label{
  font-size:.6875rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:rgb(var(--nx-accent));
}
.nexus-target__control{position:relative;display:flex;align-items:center;min-inline-size:0}
.nexus-target__select{
  -webkit-appearance:none;appearance:none;font-weight:700;padding-inline-end:1.85rem;
}
.nexus-target__chevron{
  position:absolute;inset-inline-end:.65rem;pointer-events:none;color:rgb(var(--nx-muted));font-size:.625rem;
}

/* THE POWER PAIR -- the deck hero's copy of the same choice.
   The rail closes. With the drawer shut there was no way to see, let alone
   change, the one bracket every verdict in the app is measured against, and
   0 of 202 live decks had ever had one set. So the choice sits in the hero
   next to the deck name: what you are BUILDING FOR on the left, what the deck
   actually READS AS on the right. Same handler as the rail's select
   (handleTargetBracketChange) -- one source of truth, two places to reach it.
   Tone comes from the engine's own verdict, never re-derived here. */
.nexus-power{
  --power-accent:rgb(var(--nx-accent));
  display:inline-flex;align-items:center;gap:.85rem;flex-wrap:wrap;
  padding:.45rem .7rem;border-radius:12px;
  background:color-mix(in srgb,rgb(var(--nx-surface)) 85%,transparent);backdrop-filter:blur(6px);
  border:1px solid rgb(var(--nx-track));border-inline-start:3px solid var(--power-accent);
}
.nexus-power__side{display:flex;flex-direction:column;gap:.15rem;min-inline-size:0}
.nexus-power__label{
  font-size:.5625rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:rgb(var(--nx-muted));
}
.nexus-power__control{position:relative;display:flex;align-items:center;min-inline-size:0}
.nexus-power__select{
  -webkit-appearance:none;appearance:none;font-weight:700;padding-inline-end:1.85rem;
}
.nexus-power__chevron{
  position:absolute;inset-inline-end:.6rem;pointer-events:none;color:rgb(var(--nx-muted));font-size:.625rem;
}
.nexus-power__arrow{color:rgb(var(--nx-muted));font-size:.75rem;flex:none}
.nexus-power__value{
  font-size:.9375rem;font-weight:800;color:rgb(var(--nx-text));white-space:nowrap;line-height:1.5;
}

/* Verdict tone: the same three the Intelligence panel uses, so the header and
   the panel can never disagree about what colour a deck is. */
.nexus-power--on-target{--power-accent:rgb(var(--nx-success))}
.nexus-power--under{--power-accent:rgb(var(--nx-accent))}
.nexus-power--overload{--power-accent:rgb(var(--nx-error))}
.nexus-power--overload .nexus-power__value{color:rgb(var(--nx-error))}

/* Nobody has chosen yet. Deliberately loud, and deliberately NOT a block:
   the engine still runs and still shows every number, it just stops pretending
   the question was answered. User decks ship with no bracket ON PURPOSE
   (2026-08-27, Chad) so the owner is asked rather than assigned one. */
.nexus-power--unset{--power-accent:rgb(var(--nx-warning))}
.nexus-power--unset .nexus-power__label{color:rgb(var(--nx-warning))}
.nexus-power__prompt{
  display:none; align-items:center; gap:.4rem;
  flex-basis:100%;
  font-size:.75rem; font-weight:700; line-height:1.4; color:rgb(var(--nx-warning));
}
.nexus-power--unset .nexus-power__prompt{display:flex}

/* --- one paged suggestion ------------------------------------------------- */
.nexus-swap{
  display:flex;flex-direction:column;gap:.6rem;
  padding:.85rem;border-radius:12px;background:rgb(var(--nx-surface-alt));border:1px solid rgb(var(--nx-surface-hover));
}
.nexus-swap.hidden{display:none}
.nexus-swap__head{display:flex;align-items:baseline;justify-content:space-between;gap:.5rem}
.nexus-swap__kind{
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:rgb(var(--nx-accent));
}
.nexus-swap__kind--warn{color:rgb(var(--nx-warning))}
.nexus-swap__kind--good{color:rgb(var(--nx-success))}
.nexus-swap__count{
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.625rem;color:rgb(var(--nx-muted));font-variant-numeric:tabular-nums;flex:none;
}
.nexus-swap__cards{display:flex;align-items:center;justify-content:center;gap:.5rem}
.nexus-swap__cards--pieces{gap:.35rem}
.nexus-swap__arrow{color:rgb(var(--nx-muted));font-size:.875rem;flex:none}
.nexus-swap__caption{margin:0;font-size:.75rem;line-height:1.45;color:rgb(var(--nx-text));text-align:center}
.nexus-swap__detail{margin:0;font-size:.6875rem;line-height:1.45;color:rgb(var(--nx-muted));text-align:center}
.nexus-swap__nav{display:flex;align-items:center;justify-content:center;gap:.5rem}
.nexus-swap__action,.nexus-swap__spacer{flex:1;min-inline-size:0}
.nexus-swap__step{flex:none}

/* --- a card face ----------------------------------------------------------
   Geometry knobs only; see the NEXUS_CARD_CLASS comment in the shell. The
   outgoing card is desaturated so the incoming one reads as the answer, and
   both come back to full colour on hover so you can actually read them. */
.nexus-card{
  --btn-pad-x:0;--btn-pad-y:0;--btn-min:0;--btn-radius:8px;
  position:relative;flex:none;inline-size:8.25rem;aspect-ratio:5/7;line-height:0;
}
.nexus-card__img{
  inline-size:100%;block-size:100%;object-fit:cover;
  border-radius:8px;border:2px solid rgb(var(--nx-track));background:rgb(var(--nx-base));
  transition:filter .2s ease,opacity .2s ease;
}
.nexus-card--out .nexus-card__img{border-color:rgb(var(--nx-error));filter:grayscale(.65);opacity:.72}
.nexus-card--in .nexus-card__img{border-color:rgb(var(--nx-success))}
.nexus-card--missing .nexus-card__img{border-color:rgb(var(--nx-warning));filter:grayscale(.8);opacity:.55}
.nexus-card--out:hover .nexus-card__img,
.nexus-card--missing:hover .nexus-card__img{filter:none;opacity:1}
.nexus-card__badge{
  position:absolute;inset-block-start:-.35rem;inset-inline-end:-.35rem;
  font-family:Fira Code,ui-monospace,SFMono-Regular,monospace;
  font-size:.5rem;font-weight:800;letter-spacing:.06em;line-height:1.5;
  padding:.05rem .3rem;border-radius:4px;background:rgb(var(--nx-base));border:1px solid currentColor;
}
.nexus-card--out .nexus-card__badge{color:rgb(var(--nx-error))}
.nexus-card--in .nexus-card__badge{color:rgb(var(--nx-success))}
.nexus-card--missing .nexus-card__badge{color:rgb(var(--nx-warning))}
.nexus-swap__cards--pieces .nexus-card{inline-size:6.125rem}

/* --- the close affordance on the drawer's left edge ------------------------
   The panel is open by default now, so it has to say out loud that it closes.
   A full-height strip on the edge nearest the decklist is where the eye already
   is when it wants the deck back; the header's x stays as the second way out.
   Hidden on a phone, where the sheet's grab handle and the tab bar do this. */
.nexus-drawer{position:relative}
.nexus-drawer__collapse{
  display:none;
  position:absolute;inset-block:0;inset-inline-start:0;
  --btn-pad-x:0;--btn-pad-y:0;--btn-min:0;--btn-radius:0;
  inline-size:1rem;block-size:100%;
  color:#5F708C;font-size:.625rem;
  border-inline-end:1px solid rgb(var(--nx-surface-hover));
}
.nexus-drawer__collapse:hover:not(:disabled){background:rgb(var(--nx-surface-hover));color:rgb(var(--nx-accent));border-color:rgb(var(--nx-surface-hover))}

@media (min-width:1024px){
  .nexus-drawer__collapse{display:inline-flex}
  /* clear the strip so nothing sits underneath it */
  .nexus-drawer__head{padding-inline-start:1.75rem}
  .nexus-drawer__body{padding-inline-start:1.75rem}
}

/* ==========================================================================
   TOKENS — the fourth pile in the deck workspace. Added 2026-08-29.

   A token is NOT a deck card. It never reaches the 100, the bracket, the price
   total or the legality checks: `deck_token_prints` shares no join with
   `deck_cards`, and this section renders from get_deck_tokens() alone. Because
   a fourth grid of card images under a decklist otherwise reads as part of the
   deck, the bar says "not in your 100" out loud rather than relying on layout
   to imply it.

   WHY FULL CARDS AND NOT ART CROPS (Chad, 2026-08-28): the point of this
   section is that the user has to OWN these cards. A crop is decoration; the
   card is the thing they go and buy. Same reason each tile states the
   requirement -- `1/1 red Goblin` -- and offers every printing that satisfies
   it: four different 1/1 red Goblin tokens exist, separated only by rules text,
   so "a Goblin" is not specific enough to shop from.

   RULE 1: every class here has a real rule, written here, semantically named.
   RULE 2: nothing composed at runtime -- printing tiles get literal classes.
   RULE 3: unlayered and last, same contract as the button block above.

   BUTTONS: the bar, the pips, the swap and each printing tile are real
   <button>s carrying .nexus-btn. Two of them override the component's own
   custom properties for a structural reason (a button whose entire content is
   a card image cannot keep --btn-pad-x), which is the pattern
   .nexus-drawer__collapse already established -- NOT a new size, emphasis or
   tone. No button here contains another focusable control.
   ========================================================================== */
.nexus-tokens__head{
  border-block-end:1px solid rgb(var(--nx-hair)/.1);
  margin-block-end:.875rem;
}
/* The bar is .nexus-btn--menu (full width, start-aligned, transparent); only
   the row's own spacing lives here so the button component stays untouched. */
.nexus-tokens__bar{gap:.625rem;padding-inline:0;padding-block-end:.5rem}
.nexus-tokens__bar:hover:not(:disabled){background:transparent;color:rgb(var(--nx-accent))}
.nexus-tokens__chev{
  color:rgb(var(--nx-accent));font-size:.625rem;flex:none;
  transition:transform .18s ease;
}
.nexus-tokens__bar[aria-expanded="true"] .nexus-tokens__chev{transform:rotate(90deg)}
.nexus-tokens__title{color:rgb(var(--nx-text));font-weight:700;font-size:.9375rem}
.nexus-tokens__badge{
  font-family:'Fira Code',ui-monospace,monospace;
  font-size:.59375rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:rgb(var(--nx-accent));border:1px solid rgb(var(--nx-accent)/.35);
  border-radius:999px;padding:.125rem .5rem;flex:none;
}
.nexus-tokens__hint{
  color:rgb(var(--nx-muted));font-size:.75rem;font-weight:400;
  margin-inline-start:auto;flex:none;text-transform:none;letter-spacing:normal;
}
@media (max-width:640px){.nexus-tokens__hint{display:none}}

/* --- the grid of cards --------------------------------------------------- */
.nexus-tokens__grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(8.75rem,1fr));gap:.875rem;
}
.nexus-tokens__card{display:flex;flex-direction:column;gap:.375rem;min-inline-size:0}
.nexus-tokens__frame{
  /* a button since 2026-09-02 (click opens the token full size); structural
     override of the component's padding, same as the pips below */
  --btn-pad-x:0;--btn-pad-y:0;--btn-min:0;--btn-radius:.4375rem;
  display:block;width:100%;cursor:zoom-in;
  position:relative;border-radius:.4375rem;overflow:hidden;background:#000;
  /* dashed, because the user does not own this yet -- it is a shopping list */
  border:1px dashed rgb(var(--nx-muted)/.4);
  aspect-ratio:488/680;
  transition:border-color .18s ease,transform .18s ease,box-shadow .18s ease;
}
.nexus-tokens__frame img{display:block;inline-size:100%;block-size:100%;object-fit:cover}
.nexus-tokens__card:hover .nexus-tokens__frame{
  border-color:rgb(var(--nx-accent));transform:translateY(-3px);
  box-shadow:0 6px 22px rgba(0,0,0,.6);
}
.nexus-tokens__count{
  position:absolute;inset-block-start:.3125rem;inset-inline-end:.3125rem;
  background:rgb(var(--nx-base)/.9);border:1px solid rgb(var(--nx-accent)/.5);color:rgb(var(--nx-accent));
  border-radius:999px;font-family:'Fira Code',ui-monospace,monospace;
  font-size:.59375rem;font-weight:700;padding:.0625rem .375rem;
}
/* flex:1 so a two-line requirement and a four-line one still put their swap
   buttons on the same baseline -- a ragged grid reads as broken. */
.nexus-tokens__need{font-size:.6875rem;color:rgb(var(--nx-muted));line-height:1.35;flex:1 1 auto}
.nexus-tokens__need b{color:rgb(var(--nx-slate-200));font-weight:600}
.nexus-tokens__rules{color:rgb(var(--nx-accent))}
.nexus-tokens__swap{align-self:stretch}

/* --- pips on the mainboard rows that cause a token ----------------------- */
.nexus-tokens__pips{
  display:inline-flex;gap:.25rem;align-items:center;flex:none;margin-inline-start:.375rem;
}
/* Card-shaped, because they are cards. Structural override of the button's
   own custom properties -- see the BUTTONS note at the top of this block. */
.nexus-tokens__pip{
  --btn-pad-x:0;--btn-pad-y:0;--btn-min:0;--btn-radius:2px;
  inline-size:.9375rem;block-size:1.3125rem;overflow:hidden;background:#000;
  border:1px solid rgb(var(--nx-accent)/.5);flex:none;
}
.nexus-tokens__pip img{
  inline-size:100%;block-size:100%;object-fit:cover;object-position:center 22%;
}
.nexus-tokens__pip:hover:not(:disabled){
  border-color:rgb(var(--nx-accent));box-shadow:0 0 8px rgb(var(--nx-accent)/.6);background:#000;
}
@media (pointer:coarse){
  /* the 44px floor would make a pip bigger than the row it sits in; the whole
     row is already a target, and the section below is the real control */
  .nexus-tokens__pip{--btn-min:0}
}

/* --- the printing chooser ------------------------------------------------ */
.nexus-tokens__chooser{
  border:1px solid rgb(var(--nx-accent)/.28);border-radius:.625rem;
  background:linear-gradient(180deg,rgb(var(--nx-accent)/.05),transparent);
  padding:.8125rem .9375rem;margin-block-start:.875rem;
}
.nexus-tokens__chooser-head{display:flex;align-items:baseline;gap:.625rem;flex-wrap:wrap}
.nexus-tokens__chooser-head h4{margin:0;font-size:.875rem;font-weight:700;color:rgb(var(--nx-text))}
.nexus-tokens__req{font-family:'Fira Code',ui-monospace,monospace;font-size:.6875rem;color:rgb(var(--nx-accent))}
.nexus-tokens__chooser-close{margin-inline-start:auto}
.nexus-tokens__chooser-sub{color:rgb(var(--nx-muted));font-size:.71875rem;margin:.25rem 0 .75rem}
.nexus-tokens__strip{display:flex;gap:.6875rem;overflow-x:auto;padding:.1875rem .125rem .5rem;
  /* Belt to the min-w-0 brace on the manifest column: a 93-printing strip
     is ~12,000px of min-content, and without this any flex ancestor that
     forgets min-width:0 is dragged wide by it. Scrolls in place instead. */
  min-inline-size:0;max-inline-size:100%;overscroll-behavior-x:contain}
/* Same structural override as the pip: the content is a whole card. */
.nexus-tokens__print{
  --btn-pad-x:0;--btn-pad-y:0;--btn-min:0;--btn-radius:.375rem;
  flex:none;inline-size:7.375rem;flex-direction:column;align-items:stretch;gap:0;
  background:transparent;border:0;
}
.nexus-tokens__print-frame{
  border:2px solid transparent;border-radius:.375rem;overflow:hidden;background:#000;
  aspect-ratio:488/680;transition:border-color .18s ease,box-shadow .18s ease;
}
.nexus-tokens__print-frame img{display:block;inline-size:100%;block-size:100%;object-fit:cover}
.nexus-tokens__print:hover:not(:disabled) .nexus-tokens__print-frame{border-color:rgb(var(--nx-accent)/.6)}
.nexus-tokens__print--sel .nexus-tokens__print-frame{
  border-color:rgb(var(--nx-accent));box-shadow:0 0 14px rgb(var(--nx-accent)/.45);
}
.nexus-tokens__print-meta{
  font-size:.625rem;color:rgb(var(--nx-muted));margin-block-start:.3125rem;line-height:1.3;
  text-align:start;font-weight:400;text-transform:none;letter-spacing:normal;
}
.nexus-tokens__print-set{
  display:block;font-family:'Fira Code',ui-monospace,monospace;color:rgb(var(--nx-slate-200));font-weight:700;
}
.nexus-tokens__print--sel .nexus-tokens__print-set{color:rgb(var(--nx-accent))}
.nexus-tokens__empty{
  color:rgb(var(--nx-muted));font-size:.8125rem;line-height:1.5;
  border:1px dashed rgb(var(--nx-muted)/.25);border-radius:.5rem;padding:.875rem 1rem;
}


/* ==========================================================================
   COLLECTION — the binder screen. Added 2026-08-29.

   Backed by the Phase 1 RPCs (get_collection, get_collection_shelf,
   get_collection_history). The shell renders what those return and computes
   nothing: totals, prices, set counts and the grouped/ungrouped fold are all
   decided in Postgres, which is why there is no arithmetic in the JS below.

   RULE 1: every class here has a real rule, written here, semantically named.
   RULE 2: nothing composed at runtime. Condition and finish badges use a
           literal lookup map in JS, never `nexus-coll__cond--${grade}` --
           a built name has no rule behind it and would render naked.
   RULE 3: unlayered and last, same contract as the button block above.

   BUTTONS: every control is a real <button> carrying .nexus-btn. The tile
   chevron and the flip button override --btn-pad-* for the same structural
   reason the token tiles do (a button sitting on a card image cannot keep
   its padding) -- that is not a new size, emphasis or tone. Critically, the
   chevron and flip buttons are SIBLINGS of the tile, never children of it:
   the tile itself is a button, and nesting would rewrite its accessible name.
   ========================================================================== */
.nexus-coll{display:flex;flex-direction:column;gap:1.25rem;width:100%;
  max-width:1800px;margin-inline:auto;padding:1.5rem 1rem 5rem}
@media (min-width:768px){.nexus-coll{padding-inline:2rem}}

/* --- the four headline numbers --- */
.nexus-coll__stats{display:grid;gap:.75rem;
  grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.nexus-coll__stat{background:rgb(var(--nx-surface-alt));border:1px solid rgb(var(--nx-muted)/.18);
  border-radius:.75rem;padding:.875rem 1rem}
.nexus-coll__stat-k{font-size:.6875rem;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:rgb(var(--nx-muted));margin-block-end:.375rem}
.nexus-coll__stat-v{font-family:'Fira Code',ui-monospace,monospace;
  font-size:1.375rem;font-weight:800;color:rgb(var(--nx-text));line-height:1.1}
.nexus-coll__stat-v small{display:block;font-size:.6875rem;font-weight:500;
  font-family:inherit;color:rgb(var(--nx-muted));margin-block-start:.25rem}
.nexus-coll__stat--money .nexus-coll__stat-v{color:rgb(var(--nx-success-lit))}
.nexus-coll__stat--warn{border-color:rgb(var(--nx-error-lit)/.4)}
.nexus-coll__stat--warn .nexus-coll__stat-v{color:rgb(var(--nx-error-lit))}

/* --- toolbar --- */
.nexus-coll__toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:.625rem}
.nexus-coll__search{flex:1 1 240px;min-inline-size:0}
.nexus-coll__sort{flex:none}

/* --- two-column body --- */
.nexus-coll__cols{display:flex;flex-direction:column;gap:1.25rem;min-inline-size:0}
@media (min-width:1024px){.nexus-coll__cols{flex-direction:row;align-items:flex-start}}
.nexus-coll__side{flex:none;width:100%;display:flex;flex-direction:column;gap:.25rem}
@media (min-width:1024px){.nexus-coll__side{width:15rem;
  position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}}
.nexus-coll__side-head{display:flex;align-items:center;justify-content:space-between;
  gap:.5rem;margin-block:.875rem .25rem;font-size:.6875rem;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:rgb(var(--nx-muted))}
/* A shelf row is a button, so it needs the row layout the component does not
   assume: full width, text to the start, count pinned to the end. */
.nexus-coll__shelf{width:100%;justify-content:flex-start;gap:.5rem;
  font-weight:600;text-align:start}
.nexus-coll__shelf--nested{padding-inline-start:1.75rem}
.nexus-coll__shelf-n{margin-inline-start:auto;font-family:'Fira Code',ui-monospace,monospace;
  font-size:.6875rem;color:rgb(var(--nx-muted));flex:none}
.nexus-coll__shelf[aria-current="true"] .nexus-coll__shelf-n{color:inherit}
.nexus-coll__grid-wrap{flex:1 1 auto;min-inline-size:0}

/* --- the card grid --- */
.nexus-coll__grid{display:grid;gap:1rem;
  grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
.nexus-coll__tile{position:relative;display:flex;flex-direction:column;gap:.375rem}
/* The image itself is the button: whole-tile hit area, keyboard focusable,
   and it carries no padding because its content is a card image. */
.nexus-coll__img{--btn-pad-x:0;--btn-pad-y:0;--btn-radius:.625rem;
  position:relative;display:block;width:100%;aspect-ratio:5/7;
  border:1px solid rgb(var(--nx-muted)/.2);overflow:hidden;background:rgb(var(--nx-base))}
.nexus-coll__img img{width:100%;height:100%;object-fit:cover;display:block}
.nexus-coll__tile--picked .nexus-coll__img{border-color:rgb(var(--nx-accent));
  box-shadow:0 0 0 2px rgb(var(--nx-accent)/.45)}
.nexus-coll__name{font-size:.8125rem;font-weight:700;color:rgb(var(--nx-text));line-height:1.25}
.nexus-coll__meta{display:flex;flex-wrap:wrap;align-items:center;gap:.375rem;
  font-family:'Fira Code',ui-monospace,monospace;font-size:.6875rem;color:rgb(var(--nx-muted))}
.nexus-coll__price{color:rgb(var(--nx-success-lit));font-weight:700;margin-inline-start:auto}

/* Badges sitting on the image. pointer-events:none so they never steal the
   click from the tile button underneath. */
.nexus-coll__qty,.nexus-coll__cond,.nexus-coll__loc{
  font-family:'Fira Code',ui-monospace,monospace;font-size:.625rem;font-weight:700}
.nexus-coll__qty{position:absolute;left:.375rem;bottom:.375rem;pointer-events:none;
  background:rgb(var(--nx-base)/.88);color:rgb(var(--nx-text));border-radius:999px;
  padding:.0625rem .4375rem;border:1px solid rgb(var(--nx-muted)/.3)}
/* Foil: the moving shimmer from components.css (nexus-foil-fx) on the image
   button itself; no tag. The quantity chip sits above the sweep. */
.nexus-coll__img.nexus-foil-fx{isolation:isolate}
.nexus-coll__qty{z-index:14}
/* The select pip: top-left of the tile, a sibling of the image button. Faint
   until the tile is hovered or the card is picked, then solid. The pressed
   look is the pip's own state, like .nexus-avpick__pip[aria-pressed]. */
.nexus-coll__pick{position:absolute;left:.375rem;top:.375rem;z-index:30;
  --btn-min:1.625rem;--btn-pad-x:0;--btn-pad-y:0;opacity:.55;
  background:rgb(var(--nx-base)/.8);border-color:rgb(var(--nx-muted)/.5);color:rgb(var(--nx-muted))}
.nexus-coll__tile:hover .nexus-coll__pick,.nexus-coll__pick:focus-visible,
.nexus-coll__pick[aria-pressed="true"]{opacity:1}
.nexus-coll__pick[aria-pressed="true"]{background:rgb(var(--nx-accent));border-color:rgb(var(--nx-accent));color:rgb(var(--nx-base))}
/* Drag states: the thing being dragged fades; the rail row that can take it
   lights up. */
/* --- Your Decks: drag a deck tile onto a folder ---------------------------
   Same visual language as the collection shelf above, so the two screens read
   as one gesture. .nexus-deck-drop marks a row that CAN take a deck; the
   --over modifier is added only by initDeckDragDrop, and only for a folder the
   deck is not already in. */
.nexus-deck-dragging{opacity:.4}
.nexus-deck-drop--over{outline:2px dashed rgb(var(--nx-accent));outline-offset:2px;background:rgb(var(--nx-accent)/.08)}

/* --- Folder names are never clipped --------------------------------------
   Chad, 2026-09-02: "card folder names should not be truncated." These sat
   under Tailwind's `truncate` (nowrap + ellipsis), so anything past the rail's
   width simply vanished with no way to read it. Wrapping is the honest
   behaviour: the row grows, the name stays whole. overflow-wrap catches a
   single unbroken word longer than the rail. */
.nexus-folder-name{
  min-inline-size:0;white-space:normal;overflow-wrap:anywhere;text-align:start;
}
/* The four folder-row controls are opacity:0 until hover, which HIDES them but
   still reserves ~112px of a 215px rail. With the name un-truncated that left
   it about 50px and "Competitive" wrapped one letter per line. Lifting the
   cluster out of the flow gives the name the whole row and costs the buttons
   nothing -- they only appear on hover anyway, and the tinted backdrop keeps
   them readable over the name they now sit on top of. Layout lives on this
   wrapper, never on the buttons: they stay plain .nexus-btn. */
.nexus-folder-row{position:relative}
.nexus-folder-row .nexus-row-ctls{
  position:absolute;inset-inline-end:.375rem;inset-block-start:50%;
  transform:translateY(-50%);display:flex;align-items:center;gap:.125rem;
  padding-inline-start:.75rem;border-radius:.5rem;
  /* The backdrop is what makes the buttons readable ON TOP of the name, so it
     has to appear and disappear WITH them -- left always-on it painted a solid
     block over the right third of every row and clipped the very name this
     change exists to show in full. */
  background:linear-gradient(to right,transparent,rgb(var(--nx-surface)) .75rem);
  opacity:0;pointer-events:none;transition:opacity .12s ease;
}
.nexus-folder-row:hover .nexus-row-ctls,
.nexus-folder-row:focus-within .nexus-row-ctls{opacity:1;pointer-events:auto}
@media (pointer:coarse){
  /* No hover on touch: show the cluster, and let the name wrap under it rather
     than sit beneath a permanent backdrop. */
  .nexus-folder-row .nexus-row-ctls{
    position:static;transform:none;opacity:1;pointer-events:auto;
    background:none;padding-inline-start:0;flex:none;
  }
}
/* A menu button holding a wrapped folder path has to stop centring its label
   on one line and let the button grow instead. */
.nexus-menu--wrap{align-items:flex-start;text-align:start;block-size:auto;--btn-min:0}

.nexus-coll__dragging{opacity:.4}
.nexus-coll__shelf--over{outline:2px dashed rgb(var(--nx-accent));outline-offset:2px;
  background:rgb(var(--nx-accent)/.12)}
.nexus-coll__cond{border:1px solid rgb(var(--nx-muted)/.35);color:rgb(var(--nx-slate-300));
  border-radius:.25rem;padding:.0625rem .3125rem}
.nexus-coll__loc{display:inline-flex;align-items:center;gap:.25rem;
  color:rgb(var(--nx-muted));border:1px solid rgb(var(--nx-muted)/.25);
  border-radius:999px;padding:.0625rem .4375rem;max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nexus-coll__loc--indeck{color:rgb(var(--nx-accent));border-color:rgb(var(--nx-accent)/.4)}

/* The chevron menu and the flip button are the app's EXISTING components
   (createHubActionMenu / flipGridCard), so they bring their own rules with
   them and none are repeated here. */

/* --- the unmatched-import tile: kept, never thrown away --- */
.nexus-coll__unres .nexus-coll__img{border-style:dashed;border-color:rgb(var(--nx-error-lit)/.5)}
.nexus-coll__unres-inner{display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:.375rem;height:100%;padding:.75rem;
  text-align:center;font-size:.6875rem;color:rgb(var(--nx-muted));line-height:1.5}
.nexus-coll__unres-name{color:rgb(var(--nx-error-lit));font-weight:700}

/* --- selection bar --- */
/* The selection actions sit in the toolbar (2026-09-02, replacing the fixed
   bottom bar and the Select mode). Their on/off look is painted by
   NEXUS_COLLECTION.renderBulk() with the button component's own classes. */
.nexus-coll__selbar{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}
.nexus-coll__bulk-n{font-size:.8125rem;font-weight:700;color:rgb(var(--nx-text))}
.nexus-coll__bulk-v{font-family:'Fira Code',ui-monospace,monospace;
  font-size:.75rem;color:rgb(var(--nx-success-lit));font-weight:700}

/* --- the Versions panel (grouped tile > every stack you own) --- */
.nexus-coll__vers{display:flex;flex-direction:column;gap:.75rem;max-block-size:60vh;
  overflow-y:auto;padding-inline-end:.25rem}
.nexus-coll__ver{display:flex;gap:.875rem;padding:.625rem;
  border:1px solid rgb(var(--nx-muted)/.18);border-radius:.75rem;background:rgb(var(--nx-surface-alt))}
.nexus-coll__ver-art{flex:none;width:5.5rem;aspect-ratio:5/7;border-radius:.375rem;
  overflow:hidden;background:rgb(var(--nx-base));position:relative;isolation:isolate}
.nexus-coll__ver-art img{width:100%;height:100%;object-fit:cover;display:block}
.nexus-coll__ver-body{display:flex;flex-direction:column;gap:.375rem;flex:1 1 auto;min-inline-size:0}
.nexus-coll__ver-head{display:flex;align-items:baseline;gap:.5rem;
  font-family:'Fira Code',ui-monospace,monospace;font-size:.75rem;color:rgb(var(--nx-text))}
.nexus-coll__ver-head span{color:rgb(var(--nx-muted))}
.nexus-coll__ver-actions{display:flex;flex-wrap:wrap;gap:.375rem;margin-block-start:auto}
.nexus-coll__qty-inline{font-weight:800;color:rgb(var(--nx-text))}

/* --- empty state --- */
/* --- Help page (2026-09-05) --------------------------------------------
   A question-and-answer list: the QUESTION is the heading and its answer sits
   under it (Chad's ruling on the mockup -- the first draft had them the other
   way round and read backwards). <dl>/<dt>/<dd> because that is what a
   definition list is; the styling only sets rhythm. */
.nexus-help{margin:2.5rem 0 0}
.nexus-help h2{font-size:1.125rem;font-weight:800;color:rgb(var(--nx-text));
  margin:0 0 .25rem;padding-bottom:.5rem;border-bottom:1px solid rgb(var(--nx-muted)/.18)}
.nexus-help__list{margin:0;padding:0}
.nexus-help__item{padding:1rem 0;border-bottom:1px solid rgb(var(--nx-muted)/.12)}
.nexus-help__item:last-child{border-bottom:0}
.nexus-help__item dt{font-size:1rem;font-weight:700;color:rgb(var(--nx-text));margin:0 0 .3rem}
.nexus-help__item dt a{color:rgb(var(--nx-accent));text-decoration:none}
.nexus-help__item dt a:hover,.nexus-help__item dt a:focus-visible{text-decoration:underline}
.nexus-help__item dd{margin:0;font-size:.9375rem;line-height:1.65;color:rgb(var(--nx-muted))}
.nexus-help__item dd a{color:rgb(var(--nx-accent))}
.nexus-help__item kbd{display:inline-block;background:rgb(var(--nx-surface));
  border:1px solid rgb(var(--nx-muted)/.35);border-bottom-width:2px;border-radius:.25rem;
  padding:.05rem .4rem;font-family:'Fira Code',ui-monospace,monospace;
  font-size:.8125rem;font-weight:700;color:rgb(var(--nx-text))}

/* --- Wish list (2026-09-05) --------------------------------------------
   Cards you want but do not have. The tiles reuse .nexus-coll__tile / __img /
   __qty / __name / __meta / __price wholesale; only these four are new.
   .nexus-wish__head spans the grid so the summary sits above the tiles. */
.nexus-wish__head{grid-column:1/-1}
.nexus-wish__acts{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem}
/* A wish you have since bought. The tile stays -- we never hide a user's row --
   but it reads as done, and the badge says why. */
.nexus-wish__got{position:absolute;left:.375rem;top:.375rem;z-index:14;
  pointer-events:none;font-family:'Fira Code',ui-monospace,monospace;
  font-size:.625rem;font-weight:700;border-radius:999px;padding:.0625rem .4375rem;
  background:rgb(var(--nx-success)/.92);color:#fff;
  border:1px solid rgb(var(--nx-success-lit))}
.nexus-wish--got .nexus-coll__img{border-color:rgb(var(--nx-success-lit)/.7)}
.nexus-coll__empty{grid-column:1/-1;text-align:center;padding:3rem 1rem;
  color:rgb(var(--nx-muted));font-size:.875rem;line-height:1.7}
.nexus-coll__empty h3{color:rgb(var(--nx-text));font-size:1.125rem;font-weight:800;
  margin-block-end:.5rem}

/* --- import + history dialogs --- */
.nexus-coll__paste{width:100%;min-block-size:11rem;resize:vertical;
  font-family:'Fira Code',ui-monospace,monospace;font-size:.75rem;line-height:1.6}
.nexus-coll__hist{display:flex;flex-direction:column;gap:.375rem;max-block-size:60vh;
  overflow-y:auto}
.nexus-coll__hist-row{display:flex;align-items:center;gap:.625rem;
  padding:.5rem .625rem;border:1px solid rgb(var(--nx-muted)/.18);
  border-radius:.5rem;font-size:.75rem;color:rgb(var(--nx-slate-300))}
.nexus-coll__hist-row--undone{opacity:.5}
.nexus-coll__hist-when{margin-inline-start:auto;font-family:'Fira Code',ui-monospace,monospace;
  font-size:.6875rem;color:rgb(var(--nx-muted));flex:none}

/* =========================================================================
   THE OWNERSHIP LAYER  (treatment A, approved by Chad 2026-08-29)
   The ribbon rides the BOTTOM edge of a card tile because every other margin
   is already claimed: top-left is BANNED / ILLEGAL / GC, top-right is the
   chevron menu, the right edge is the flip button and bottom-left is the
   quantity chip. The bottom strip is also the only one wide enough to carry a
   place name, which is the whole point of the feature.
   State modifiers are LITERAL class names looked up from a map in JS -- never
   composed at runtime -- so this stylesheet stays greppable.
   ========================================================================= */
.nexus-own__rib{position:absolute;inset-inline:0;inset-block-end:0;z-index:15;
  display:flex;align-items:center;justify-content:center;gap:.3125rem;
  padding:.25rem .375rem;font-size:.625rem;font-weight:700;line-height:1.2;
  border-block-start:1px solid transparent;border-end-start-radius:.6875rem;
  border-end-end-radius:.6875rem;backdrop-filter:blur(6px);white-space:nowrap;
  overflow:hidden;pointer-events:none}
/* The label lives in its own span: text-overflow cannot reach the anonymous
   flex item a bare text node becomes, so a long deck-box name lost its first
   word to the clip instead of ending in an ellipsis. */
.nexus-own__rib-txt{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nexus-own__rib--free{background:rgb(var(--nx-success)/.88);color:#fff;
  border-block-start-color:rgb(var(--nx-success-lit)/.7)}
.nexus-own__rib--committed{background:rgb(var(--nx-warning)/.9);color:#1C1206;
  border-block-start-color:rgb(var(--nx-rare)/.75)}
.nexus-own__rib--print{background:rgb(var(--nx-slate-800)/.92);color:rgb(var(--nx-slate-300));
  border-block-start-color:rgb(var(--nx-muted)/.45)}
.nexus-own__rib--missing{background:rgb(var(--nx-error)/.86);color:#fff;
  border-block-start-color:rgb(var(--nx-error-lit)/.7)}
/* A card you do not own reads as absent at a glance, without being hidden. */
.nexus-own-missing img{opacity:.4;filter:grayscale(.85)}
/* Discover tiles carry a price chip in the bottom-left corner, which is the
   corner the ribbon claims. With the overlay on, the chip steps up above it
   instead of one covering the other. (Chad 2026-09-02, the hub overlay.) */
.nexus-own-on .nexus-price-badge{bottom:1.6875rem}

/* list-view pills */
.nexus-own__pill{display:inline-flex;align-items:center;gap:.3125rem;flex:none;
  font-size:.625rem;font-weight:700;border-radius:9999px;padding:.125rem .625rem}
.nexus-own__pill--free{color:rgb(var(--nx-success-lit));border:1px solid rgb(var(--nx-success)/.5);
  background:rgb(var(--nx-success)/.12)}
.nexus-own__pill--committed{color:rgb(var(--nx-rare));border:1px solid rgb(var(--nx-warning)/.5);
  background:rgb(var(--nx-warning)/.12)}
.nexus-own__pill--print{color:rgb(var(--nx-muted));border:1px solid rgb(var(--nx-muted)/.35)}
.nexus-own__pill--missing{color:rgb(var(--nx-error-lit));border:1px solid rgb(var(--nx-error)/.45);
  background:rgb(var(--nx-error)/.09)}

/* summary strip above the buckets */
.nexus-own__bar{display:flex;align-items:center;gap:1.375rem;flex-wrap:wrap;
  padding:.6875rem 1.125rem;border:1px solid rgb(var(--nx-success)/.28);
  border-radius:.75rem;background:rgb(var(--nx-success)/.07)}
.nexus-own__bar-big{font-weight:900;font-size:.9375rem;color:rgb(var(--nx-success-lit))}
.nexus-own__bar-met{font-size:.71875rem;color:rgb(var(--nx-muted))}
.nexus-own__bar-met b{color:rgb(var(--nx-slate-200));font-weight:700}
.nexus-own__meter{flex:1;min-inline-size:9.375rem;block-size:.4375rem;
  border-radius:9999px;background:rgb(var(--nx-muted)/.18);overflow:hidden;display:flex}
.nexus-own__meter i{display:block;block-size:100%}
.nexus-own__meter i.is-free{background:rgb(var(--nx-success))}
.nexus-own__meter i.is-committed{background:rgb(var(--nx-warning))}
.nexus-own__meter i.is-print{background:rgb(var(--nx-muted)/.65)}

/* Precons tab, treatment D (Chad 2026-09-02): the bar and its words live BELOW
   the tile, touching no artwork at all. The wrapper is the grid child, so the
   art keeps its own aspect ratio and the bar simply follows it. */
.nexus-own__precon-wrap{display:flex;flex-direction:column}
.nexus-own__precon{margin-block-start:.5rem}
.nexus-own__precon .nexus-own__meter{flex:none;min-inline-size:0;inline-size:100%}
.nexus-own__legend{display:flex;flex-wrap:wrap;gap:.375rem .75rem;
  margin-block-start:.4375rem;font-size:.6875rem;color:rgb(var(--nx-muted));line-height:1.3}
.nexus-own__legend span{display:flex;align-items:center;gap:.3125rem}
.nexus-own__legend b{color:rgb(var(--nx-slate-200));font-weight:700}
.nexus-own__legend-lead{color:rgb(var(--nx-success-lit));font-weight:700}
.nexus-own__legend-lead b{color:rgb(var(--nx-success-lit))}
.nexus-own__key{inline-size:.5rem;block-size:.5rem;border-radius:2px;
  display:inline-block;flex:none}
.nexus-own__key.is-free{background:rgb(var(--nx-success))}
.nexus-own__key.is-committed{background:rgb(var(--nx-warning))}
.nexus-own__key.is-print{background:rgb(var(--nx-muted)/.65)}
.nexus-own__key.is-missing{background:rgb(var(--nx-muted)/.18)}

/* the where-is-it breakdown inside the card details modal */
.nexus-own__where{display:flex;flex-direction:column;gap:.375rem;margin-block-start:.75rem}
.nexus-own__where-row{display:flex;align-items:center;gap:.5625rem;
  padding:.5rem .625rem;border:1px solid rgb(var(--nx-muted)/.18);
  border-radius:.5rem;font-size:.75rem;color:rgb(var(--nx-slate-300))}
.nexus-own__where-row .lo{flex:1;line-height:1.35}
.nexus-own__where-row .lo small{display:block;color:rgb(var(--nx-muted));font-size:.65625rem}
.nexus-own__where-row .n{font-family:'Fira Code',ui-monospace,monospace;
  font-size:.71875rem;font-weight:700;color:rgb(var(--nx-success-lit));flex:none}
.nexus-own__where-row--used{border-color:rgb(var(--nx-warning)/.4)}

/* ==========================================================================
   ACCOUNT — the profile / sign-in / danger pages (#/account/*), 2026-08-29.
   Every class here has a hand-written rule, per THE RULES at the top of this
   block. Nothing is composed at runtime; the section a pane belongs to is a
   data-attribute, not part of a class name.

   WHY ITS OWN LAYOUT and not the modal it replaces: the old profile modal was
   max-w-sm (384px) and held a display name and two buttons. Email, password,
   linked providers, export and deletion do not fit a 384px box, and a password
   field sitting next to a display-name field invites the browser to autofill
   the wrong one. Each destination is a routed page instead.
   ========================================================================== */
.nexus-acct{display:grid;grid-template-columns:14rem 1fr;min-block-size:100%;
  inline-size:100%;max-inline-size:80rem;margin-inline:auto}
/* One column on phones: the rail becomes a scrolling strip above the pane. */
@media (max-width:860px){
  .nexus-acct{grid-template-columns:1fr}
}

.nexus-acct__rail{border-inline-end:1px solid rgb(var(--nx-surface));padding:1.125rem .75rem;
  background:rgb(var(--nx-surface)/.35)}
@media (max-width:860px){
  .nexus-acct__rail{border-inline-end:0;border-block-end:1px solid rgb(var(--nx-surface));
    display:flex;gap:.375rem;overflow-x:auto;padding:.75rem}
  .nexus-acct__rail .nexus-acct__grp{display:none}
  .nexus-acct__rail .nexus-btn{inline-size:auto;flex:none}
}
.nexus-acct__grp{font-family:'Fira Code',ui-monospace,monospace;font-size:.625rem;
  letter-spacing:.16em;text-transform:uppercase;color:rgb(var(--nx-muted));
  padding-inline:.625rem;margin-block:.875rem .375rem}
.nexus-acct__grp:first-child{margin-block-start:0}
/* The rail buttons are .nexus-btn--menu; this only marks the active one, and
   it owns no chrome of its own. The second selector is what replaced a pair of
   !important declarations (2026-08-29): .nexus-btn--menu:hover is (0,3,0), so
   a bare (0,1,0) marker lost the moment you moused over the lit item and the
   active page stopped looking active. Matching the hover's specificity and
   sitting later in source wins it honestly. */
.nexus-btn--menu.nexus-acct__nav-on,
.nexus-btn--menu.nexus-acct__nav-on:hover{background:rgb(var(--nx-accent)/.1);color:rgb(var(--nx-accent))}

.nexus-acct__pane{padding:1.625rem 1.875rem 4rem;min-inline-size:0}
.nexus-acct__title{font-family:Outfit,ui-sans-serif,system-ui,sans-serif;
  font-weight:900;font-size:1.1875rem;color:rgb(var(--nx-text));margin-block-end:.1875rem}
.nexus-acct__lede{color:rgb(var(--nx-muted));font-size:.78125rem;line-height:1.55;
  margin-block-end:1.375rem;max-inline-size:64ch}
.nexus-acct__card{border:1px solid rgb(var(--nx-surface));border-radius:.6875rem;
  background:rgb(var(--nx-surface));padding:1.125rem 1.25rem;margin-block-end:1rem;
  max-inline-size:52rem}
.nexus-acct__card h3{font-family:'Fira Code',ui-monospace,monospace;font-size:.625rem;
  font-weight:700;letter-spacing:.15em;text-transform:uppercase;color:rgb(var(--nx-accent));
  margin-block-end:.875rem;padding-block-end:.5625rem;border-block-end:1px solid rgb(var(--nx-surface-hover))}

/* identity strip */
.nexus-acct__id{display:flex;gap:1.25rem;align-items:center;flex-wrap:wrap}
.nexus-acct__avwrap{position:relative;flex:none}
/* The avatar is a real .nexus-btn (--tinted --icon --pill) plus the shared
   .nexus-avatar-host/.nexus-avatar-img pair the header already uses. It had a
   hand-rolled button signature here until 2026-08-29 -- its own border,
   background, cursor, padding and hover -- which is exactly the duplication
   the button system exists to stop. All this class contributes now is the one
   thing the system cannot know, fed through the system's OWN --btn-* API:
   how big an avatar is. Clipping is ours because the art overflows the pill. */
.nexus-acct__av{--btn-min:6rem;overflow:hidden}
.nexus-acct__av-ov{position:absolute;inset:0;display:grid;place-items:center;
  background:rgb(var(--nx-base)/.78);opacity:0;transition:opacity .15s;
  font-size:.59375rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:rgb(var(--nx-text))}
.nexus-acct__av:hover .nexus-acct__av-ov,
.nexus-acct__av:focus-visible .nexus-acct__av-ov{opacity:1}
/* Visible at rest: a coarse pointer has no hover, so the pencil is the only
   affordance a touch user ever sees. pointer-events:none keeps the button
   underneath it the single click target. */
.nexus-acct__av-badge{position:absolute;inset-inline-end:0;inset-block-end:.125rem;
  block-size:1.75rem;inline-size:1.75rem;border-radius:50%;background:rgb(var(--nx-accent));
  color:rgb(var(--nx-base));border:3px solid rgb(var(--nx-base));display:grid;place-items:center;
  font-size:.75rem;pointer-events:none}
.nexus-acct__name{font-family:Outfit,ui-sans-serif,system-ui,sans-serif;
  font-weight:900;font-size:1.3125rem;line-height:1.15;color:rgb(var(--nx-text))}
.nexus-acct__sub{color:rgb(var(--nx-muted));font-size:.78125rem;margin-block-start:.125rem}
.nexus-acct__stats{display:flex;gap:1rem;margin-block-start:.6875rem;flex-wrap:wrap}
.nexus-acct__stat{font-size:.71875rem;color:rgb(var(--nx-muted))}
.nexus-acct__stat b{display:block;color:rgb(var(--nx-text));font-weight:700;
  font-family:'Fira Code',ui-monospace,monospace;font-size:.8125rem}
.nexus-acct__credit{font-size:.6875rem;color:rgb(var(--nx-muted));margin-block-start:.5625rem;
  font-style:italic}

/* fields */
.nexus-acct__grid{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
@media (max-width:700px){.nexus-acct__grid{grid-template-columns:1fr}}
.nexus-acct__f{display:block;min-inline-size:0}
.nexus-acct__f label{display:flex;align-items:center;gap:.4375rem;flex-wrap:wrap;
  font-size:.65625rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:rgb(var(--nx-muted));margin-block-end:.375rem}
.nexus-acct__help{font-size:.71875rem;color:rgb(var(--nx-muted));margin-block-start:.375rem;
  line-height:1.5}
.nexus-acct__help b{color:rgb(var(--nx-text))}
.nexus-acct__count{margin-inline-start:auto;font-family:'Fira Code',ui-monospace,monospace;
  font-size:.625rem;color:rgb(var(--nx-muted));font-weight:400;letter-spacing:0}
.nexus-acct__pill{font-size:.5625rem;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;padding:.125rem .4375rem;border-radius:9999px}
.nexus-acct__pill--public{background:rgb(var(--nx-accent)/.13);color:rgb(var(--nx-accent))}
.nexus-acct__pill--private{background:rgb(var(--nx-muted)/.16);color:rgb(var(--nx-muted))}
.nexus-acct__pill--ok{background:rgb(var(--nx-success)/.18);color:rgb(var(--nx-success-lit))}
.nexus-acct__pill--warn{background:rgb(var(--nx-warning)/.18);color:rgb(var(--nx-rare))}

.nexus-acct__actions{display:flex;gap:.625rem;align-items:center;flex-wrap:wrap;
  margin-block-start:1.25rem;padding-block-start:1rem;border-block-start:1px solid rgb(var(--nx-surface-hover))}
.nexus-acct__spacer{flex:1}
.nexus-acct__saved{font-size:.71875rem;color:rgb(var(--nx-success-lit))}

/* settings rows */
.nexus-acct__row{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;
  padding-block:.875rem;border-block-end:1px solid rgb(var(--nx-surface-hover))}
.nexus-acct__row:last-child{border-block-end:0;padding-block-end:0}
.nexus-acct__row-t{flex:1;min-inline-size:12rem}
.nexus-acct__row-l{font-size:.84375rem;font-weight:700;color:rgb(var(--nx-text));
  display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.nexus-acct__row-v{font-size:.78125rem;color:rgb(var(--nx-muted));margin-block-start:.1875rem;
  line-height:1.5;overflow-wrap:anywhere}
.nexus-acct__row-v b{color:rgb(var(--nx-text));font-weight:600}
.nexus-acct__prov{block-size:1.875rem;inline-size:1.875rem;border-radius:.5rem;
  display:grid;place-items:center;font-size:.8125rem;flex:none;color:#fff}

/* explainer / warning boxes */
.nexus-acct__box{border:1px solid rgb(var(--nx-surface-hover));border-radius:.5625rem;
  padding:.8125rem .9375rem;background:rgb(var(--nx-accent)/.045);font-size:.78125rem;
  line-height:1.6;color:rgb(var(--nx-muted))}
.nexus-acct__box b{color:rgb(var(--nx-text))}
.nexus-acct__box--warn{background:rgb(var(--nx-warning)/.07);border-color:rgb(var(--nx-warning)/.3)}
.nexus-acct__box--danger{background:rgb(var(--nx-error)/.07);border-color:rgb(var(--nx-error)/.3)}

.nexus-acct__crumbs{font-family:'Fira Code',ui-monospace,monospace;font-size:.65625rem;
  color:rgb(var(--nx-track));margin-block-end:.1875rem}
.nexus-acct__crumbs b{color:rgb(var(--nx-muted));font-weight:400}

/* password strength — four segments, filled by a data attribute rather than a
   composed class name (RULE 2). */
.nexus-acct__meter{display:flex;gap:.25rem;margin-block-start:.5625rem}
.nexus-acct__meter i{flex:1;block-size:.25rem;border-radius:.125rem;background:rgb(var(--nx-surface-hover))}
.nexus-acct__meter[data-score="1"] i:nth-child(-n+1){background:rgb(var(--nx-error))}
.nexus-acct__meter[data-score="2"] i:nth-child(-n+2){background:rgb(var(--nx-warning))}
.nexus-acct__meter[data-score="3"] i:nth-child(-n+3){background:rgb(var(--nx-warning))}
.nexus-acct__meter[data-score="4"] i{background:rgb(var(--nx-success))}
.nexus-acct__reqs{list-style:none;padding:0;margin:.6875rem 0 0;font-size:.75rem;
  color:rgb(var(--nx-muted))}
.nexus-acct__reqs li{display:flex;align-items:center;gap:.5rem;padding-block:.15625rem}
.nexus-acct__reqs li::before{content:'\25CB';font-family:'Fira Code',ui-monospace,monospace;
  font-size:.6875rem;inline-size:.75rem}
.nexus-acct__reqs li[data-met="1"]{color:rgb(var(--nx-success-lit))}
.nexus-acct__reqs li[data-met="1"]::before{content:'\2713'}

/* ---- avatar picker ---- */
.nexus-avpick{position:fixed;inset:0;z-index:110;display:flex;align-items:center;
  justify-content:center;padding:1rem;background:rgb(var(--nx-base)/.86)}
.nexus-avpick__box{inline-size:100%;max-inline-size:60rem;max-block-size:90vh;
  display:flex;flex-direction:column;background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
  border-radius:.8125rem;box-shadow:0 24px 60px rgba(0,0,0,.6);overflow:hidden}
.nexus-avpick__head{padding:1rem 1.25rem;border-block-end:1px solid rgb(var(--nx-surface-hover));flex:none}
.nexus-avpick__title{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap}
.nexus-avpick__title h3{font-family:Outfit,ui-sans-serif,system-ui,sans-serif;
  font-weight:900;font-size:1.0625rem;color:rgb(var(--nx-text))}
.nexus-avpick__sub{font-size:.75rem;color:rgb(var(--nx-muted));margin-block-start:.25rem}
.nexus-avpick__ctl{display:flex;gap:.625rem;align-items:center;
  margin-block-start:.875rem;flex-wrap:wrap}
.nexus-avpick__search{flex:1;min-inline-size:14rem}
.nexus-avpick__pips{display:flex;gap:.3125rem}
/* The five colour pips plus colourless. Each is a .nexus-btn
   (--sm --solid --icon --pill), so border, cursor, centring, focus ring,
   press animation and touch target all come from the button system; these
   classes only feed it a fill through its own --btn-accent variable. They ARE
   literal classes with real rules -- never composed from card data at runtime.
   A mana colour is not a tone: tones encode CONSEQUENCE (danger, success),
   and a filter pip has none, so the palette is set here rather than by adding
   six tones to the system. --btn-size is restored from --icon's 18px because
   these hold a letter, not a glyph. */
.nexus-avpick__pip{--btn-size:.75rem;font-weight:900;opacity:.45}
.nexus-avpick__pip[aria-pressed="true"]{opacity:1;border-color:rgb(var(--nx-accent));
  box-shadow:0 0 10px rgb(var(--nx-accent)/.5)}
.nexus-avpick__pip--w{--btn-accent:rgb(var(--nx-mtg-w))}
.nexus-avpick__pip--u{--btn-accent:rgb(var(--nx-mtg-u))}
.nexus-avpick__pip--b{--btn-accent:rgb(var(--nx-mtg-b))}
.nexus-avpick__pip--r{--btn-accent:rgb(var(--nx-mtg-r))}
.nexus-avpick__pip--g{--btn-accent:rgb(var(--nx-mtg-g))}
.nexus-avpick__pip--c{--btn-accent:rgb(var(--nx-mtg-c))}
.nexus-avpick__body{padding:1rem 1.25rem .25rem;overflow-y:auto;flex:1;min-block-size:0}
.nexus-avpick__grid{display:grid;
  grid-template-columns:repeat(auto-fill,minmax(5.25rem,1fr));gap:.875rem}
/* A tile is a .nexus-btn --md --ghost turned on its side. The system supplies
   the reset, the hover plate, the focus ring and the press animation; this
   sets only the axis and trims the padding through --btn-pad-*, because 3,453
   tiles at the default 1rem inline padding would fit four to a row. */
.nexus-avpick__tile{--btn-pad-x:.25rem;--btn-pad-y:.375rem;
  flex-direction:column;gap:.375rem;font-weight:400}
.nexus-avpick__ring{block-size:4.5rem;inline-size:4.5rem;border-radius:50%;
  overflow:hidden;position:relative;border:2px solid transparent;background:rgb(var(--nx-surface-hover));
  transition:border-color .12s,transform .12s}
.nexus-avpick__ring img{inline-size:100%;block-size:100%;object-fit:cover;
  object-position:50% 28%;display:block}
.nexus-avpick__tile:hover .nexus-avpick__ring,
.nexus-avpick__tile:focus-visible .nexus-avpick__ring{border-color:rgb(var(--nx-accent));
  transform:translateY(-2px)}
.nexus-avpick__tile[aria-pressed="true"] .nexus-avpick__ring{border-color:rgb(var(--nx-accent));
  box-shadow:0 0 0 2px rgb(var(--nx-surface)),0 0 0 4px rgb(var(--nx-accent))}
.nexus-avpick__tile[aria-pressed="true"] .nexus-avpick__ring::after{content:'\2713';
  position:absolute;inset-inline-end:.125rem;inset-block-end:.125rem;block-size:1.1875rem;
  inline-size:1.1875rem;border-radius:50%;background:rgb(var(--nx-accent));color:rgb(var(--nx-base));
  font-size:.6875rem;font-weight:900;display:grid;place-items:center;
  border:2px solid rgb(var(--nx-surface))}
.nexus-avpick__cap{font-size:.625rem;line-height:1.25;color:rgb(var(--nx-muted));text-align:center;
  max-inline-size:5.25rem;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;
  line-clamp:2;-webkit-box-orient:vertical}
.nexus-avpick__tile:hover .nexus-avpick__cap{color:rgb(var(--nx-text))}
.nexus-avpick__rk{font-family:'Fira Code',ui-monospace,monospace;font-size:.5625rem;
  color:rgb(var(--nx-track))}
.nexus-avpick__more{text-align:center;padding-block:.875rem 1.125rem}
.nexus-avpick__foot{padding:.8125rem 1.25rem;border-block-start:1px solid rgb(var(--nx-surface-hover));
  display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;
  background:rgb(var(--nx-base)/.4);flex:none}
.nexus-avpick__picked{display:flex;align-items:center;gap:.625rem;font-size:.78125rem;
  color:rgb(var(--nx-muted))}
.nexus-avpick__picked img{block-size:2.125rem;inline-size:2.125rem;border-radius:50%;
  object-fit:cover;object-position:50% 28%;border:1px solid rgb(var(--nx-accent))}
.nexus-avpick__picked b{color:rgb(var(--nx-text));display:block;font-size:.8125rem}
.nexus-avpick__empty{color:rgb(var(--nx-muted));font-size:.8125rem;text-align:center;
  padding-block:2.5rem}

/* THE GUARD. Same lesson as .nexus-btn and .nexus-field above: this block is
   unlayered and appended LAST, so every display:flex/block/grid in it beats
   the utility .hidden{display:none} on source order at equal specificity, and
   `.nexus-acct__av img` (0,1,1) beats it outright. Without these, adding
   `hidden` in JS silently does nothing. Caught in the browser on 2026-08-29:
   the Admin sandbox row rendered for a non-admin account, and the empty avatar
   <img> stayed visible behind the fallback icon. */
.nexus-acct__row.hidden,
.nexus-acct__f.hidden,
.nexus-acct__id.hidden,
.nexus-acct__meter.hidden,
.nexus-acct__actions.hidden,
.nexus-acct__stats.hidden,
.nexus-acct__reqs.hidden,
.nexus-acct__pill.hidden,
.nexus-acct__saved.hidden,
.nexus-avpick.hidden,
.nexus-avpick__ctl.hidden,
.nexus-avpick__grid.hidden,
.nexus-avpick__foot.hidden,
.nexus-avpick__tile.hidden,
.nexus-avpick__picked.hidden,
.nexus-avatar-img.hidden{display:none}

/* The small round avatar in the global header.
   .nexus-btn--icon sizes itself from --btn-min plus aspect-ratio:1, and
   min-block-size is a MINIMUM: a 626x457 Scryfall art_crop dropped in as a
   normal flow child expands the button to the image's natural size and tears
   the header apart. Taking the image out of flow pins it to the button
   instead. This could not have been noticed before 2026-08-29 -- the old
   uploader could never write a file, so avatar_url was null for every user
   and this code path had never once run with a real image in it. */
.nexus-avatar-host{position:relative}
.nexus-avatar-img{position:absolute;inset:0;inline-size:100%;block-size:100%;
  object-fit:cover;object-position:50% 30%;border-radius:inherit;
  max-inline-size:none}

/* --- Public content pages (Phase 4 of the Astro conversion, 2026-09-01) ---
   Card, index and pill links are scoped under .nexus-page so they outrank the
   page-wide `.nexus-page a:not(.nexus-btn)` underline (same specificity, later).
   /commanders, /precons, /archetypes, /themes, /tags, /glossary, /brackets,
   /legal. Semantic names, hand-written, nothing composed at runtime (RULE 2).
   Tokens from the header: base #080b12, surface #101623, border #171E2D,
   text #F8FAFC, muted #94A3B8, blue #00E1FF, violet #7C3AED. */
/* --- THE SITE FOOTER -------------------------------------------------------
   Rebuilt into columns 2026-09-02 (Chad: the Explore links "should not be
   listed all cramped together in a footer"). LAYOUT ONLY: the grid, the column
   stacks and the headings. Every control inside is an unmodified
   .nexus-btn --md --ghost, so nothing here touches button geometry or colour.
   The columns collapse to a single stack under 640px, where a four-across grid
   is unreadable anyway. */
.nexus-foot{
  inline-size:100%;border-block-start:1px solid rgb(var(--nx-surface-hover));background:rgb(var(--nx-base));
  padding-block:2.5rem 2rem;margin-block-start:auto;flex-shrink:0;z-index:50;
}
.nexus-foot__inner{
  max-inline-size:80rem;margin-inline:auto;padding-inline:1.5rem;
  display:grid;gap:2rem 2.5rem;
  grid-template-columns:minmax(16rem,2fr) repeat(3,minmax(8rem,1fr));
  align-items:start;
}
.nexus-foot__about{display:flex;flex-direction:column;gap:.625rem}
.nexus-foot__brand{
  margin:0;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  font-size:.8125rem;color:rgb(var(--nx-text));
}
.nexus-foot__fan{
  margin:0;font-family:'Fira Code',ui-monospace,monospace;font-size:.6875rem;
  /* Solid, no opacity: rgb(var(--nx-muted)) at .6 over the rgb(var(--nx-base)) footer blended to
     #5d6879, a 3.39:1 contrast that failed Lighthouse (2026-09-02); text
     this small needs 4.5:1. rgb(var(--nx-muted)) is the same slate a shade dimmer, 5.9:1. */
  line-height:1.6;color:rgb(var(--nx-muted));max-inline-size:44ch;
}
.nexus-foot__copy{margin:0;font-size:.75rem;font-weight:700;color:rgb(var(--nx-slate-200))}
/* The link stacks. align-items:start keeps a ghost button from spanning the
   whole column, so the hover target matches the word. */
.nexus-foot__col{display:flex;flex-direction:column;align-items:flex-start;gap:.125rem}
.nexus-foot__head{
  margin:0 0 .375rem;font-size:.6875rem;font-weight:800;letter-spacing:.12em;
  text-transform:uppercase;color:rgb(var(--nx-accent));
}
@media (max-width:639px){
  .nexus-foot__inner{grid-template-columns:1fr;gap:1.75rem}
  .nexus-foot__about{align-items:flex-start}
}
/* Kept: .nexus-explore was the single centred row this block replaced. The app
   shell has no other user, but the class is cheap and removing a rule whose
   only proof of death is a static scan is exactly what the CSS ruling forbids. */
.nexus-explore{display:flex;flex-wrap:wrap;justify-content:center;gap:.25rem .5rem}
/* inline-size:100% is load-bearing (2026-09-05). <main> is a flex item in a
   column flex container, and `margin-inline:auto` on a flex item CANCELS the
   default stretch — the auto margins eat the free space and the box
   shrink-wraps to its content. Measured on /news with nothing published: 624px
   wide inside a 1440px window, floating right of centre, while the footer
   below it sat at the correct 1280px. Every content page shipped so far has
   content wide enough to hide it. This is a no-op for those and the fix for
   any page whose content is narrow. */
.nexus-page{inline-size:100%;max-inline-size:80rem;margin-inline:auto;padding:2.5rem 1.5rem 4rem;color:rgb(var(--nx-text))}
.nexus-page a:not(.nexus-btn){color:rgb(var(--nx-accent));text-decoration:underline;text-underline-offset:.15em}
.nexus-page a.nexus-btn{text-decoration:none}
.nexus-crumbs{display:flex;flex-wrap:wrap;gap:.35rem;font-size:.75rem;color:rgb(var(--nx-muted));margin-block-end:1.5rem;list-style:none;padding:0}
.nexus-crumbs li+li::before{content:"/";margin-inline-end:.35rem;color:rgb(var(--nx-track))}
.nexus-page__title{font-size:clamp(1.75rem,4vw,2.75rem);font-weight:900;line-height:1.1;letter-spacing:-.02em;margin:0 0 .5rem}
.nexus-page__lede{font-size:1.05rem;color:rgb(var(--nx-muted));max-inline-size:60ch;margin:0 0 2rem;line-height:1.6}
.nexus-page__hero{display:grid;gap:2rem;align-items:start;margin-block-end:2.5rem}
@media (min-width:768px){.nexus-page__hero{grid-template-columns:minmax(0,18rem) minmax(0,1fr)}}
/* block-size:auto: the commander page's art carries width/height (488x680) to
   reserve its box before it loads; this keeps the height attribute from ever
   sizing the picture. The --wide variant's aspect-ratio still applies. */
.nexus-page__art{inline-size:100%;block-size:auto;border-radius:1rem;border:1px solid rgb(var(--nx-surface-hover));box-shadow:0 20px 40px rgb(0 0 0/.5)}
.nexus-page__art--wide{aspect-ratio:16/9;object-fit:cover}
.nexus-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(11rem,1fr));gap:.75rem;margin:0 0 1.5rem;padding:0;list-style:none}
.nexus-facts li{background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));border-radius:.75rem;padding:.75rem 1rem}
.nexus-facts b{display:block;font-size:.65rem;letter-spacing:.12em;text-transform:uppercase;color:rgb(var(--nx-muted));margin-block-end:.25rem}
.nexus-oracle p{margin:0 0 .75rem;line-height:1.6}
.nexus-section{margin-block-start:2.5rem}
.nexus-section__title{font-size:1.25rem;font-weight:800;margin:0 0 1rem}
.nexus-pills{display:flex;flex-wrap:wrap;gap:.5rem;padding:0;margin:0;list-style:none}
.nexus-page .nexus-pills a{display:inline-block;background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));border-radius:999px;padding:.35rem .8rem;font-size:.8rem;font-weight:700;color:rgb(var(--nx-text));text-decoration:none}
.nexus-page .nexus-pills a:hover{border-color:rgb(var(--nx-accent));color:rgb(var(--nx-accent))}
.nexus-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(14rem,1fr));gap:1rem;padding:0;margin:0;list-style:none}
.nexus-cards li{background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));border-radius:1rem;overflow:hidden}
.nexus-page .nexus-cards a{display:block;color:inherit;text-decoration:none}
.nexus-cards img{inline-size:100%;aspect-ratio:16/9;object-fit:cover;display:block;background:rgb(var(--nx-card))}
.nexus-cards__body{padding:.85rem 1rem}
.nexus-cards__name{font-weight:800;margin:0 0 .25rem}
.nexus-cards__meta{font-size:.75rem;color:rgb(var(--nx-muted));margin:0}
.nexus-index{columns:14rem;column-gap:2rem;padding:0;margin:0;list-style:none;font-size:.9rem;line-height:1.7}
.nexus-index li{break-inside:avoid}
.nexus-page .nexus-index a{color:rgb(var(--nx-text));text-decoration:none}
.nexus-page .nexus-index a:hover{color:rgb(var(--nx-accent))}
.nexus-letter{font-size:1rem;font-weight:900;color:rgb(var(--nx-accent));margin:2rem 0 .75rem;letter-spacing:.1em}
.nexus-decklist{display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));gap:1.5rem}
.nexus-decklist ul{padding:0;margin:0;list-style:none;font-size:.9rem;line-height:1.7}
.nexus-decklist h3{font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:rgb(var(--nx-muted));margin:0 0 .5rem;border-block-end:1px solid rgb(var(--nx-surface-hover));padding-block-end:.35rem}
.nexus-decklist .nexus-qty{color:rgb(var(--nx-muted));font-variant-numeric:tabular-nums;margin-inline-end:.4rem}
/* --- Card and glossary references inside a taxonomy description ----------
   The built content pages carry no app script, so the app's cursor-follow card
   preview is not available here. Hover and keyboard focus reveal the art in
   pure CSS instead, anchored to the name; the link itself works with no CSS and
   no JS at all, which is the part that matters to a crawler and to a reader on
   a phone (where there is no hover and the tap just goes to the card). */
/* Specificity note: the page-wide `.nexus-page a:not(.nexus-btn)` rule below
   underlines every link on a content page and is (0,2,0). A bare .nexus-cardref
   is (0,1,0) and loses, which left a solid underline stacked on top of the
   dotted border. Matched at (0,2,0) so the dotted treatment is the only one. */
.nexus-page a.nexus-cardref,
.nexus-compose__preview a.nexus-cardref{
  position:relative;color:rgb(var(--nx-text));font-weight:700;text-decoration:none;
  border-block-end:1px dotted rgb(var(--nx-accent)/.7);
}
.nexus-page a.nexus-cardref:hover,.nexus-page a.nexus-cardref:focus-visible,
.nexus-compose__preview a.nexus-cardref:hover,.nexus-compose__preview a.nexus-cardref:focus-visible{color:rgb(var(--nx-accent))}
.nexus-cardref__art{
  position:absolute;inset-block-end:calc(100% + .5rem);inset-inline-start:0;
  inline-size:15rem;max-inline-size:60vw;border-radius:.5rem;z-index:40;
  border:1px solid rgb(var(--nx-accent)/.45);box-shadow:0 12px 32px rgba(0,0,0,.65);
  opacity:0;visibility:hidden;transition:opacity .15s ease;pointer-events:none;
}
.nexus-cardref:hover .nexus-cardref__art,
.nexus-cardref:focus-visible .nexus-cardref__art{opacity:1;visibility:visible}
/* A bolded term the glossary defines becomes a link to its entry; one it does
   not stays a plain <strong>, so nothing ever points at a missing anchor. */
/* The composer's preview is included on every one of these so that what the
   writer sees is the article's real treatment, not a plain-text approximation
   — the same reason the preview is rendered by the shipped SQL function rather
   than a second renderer (2026-09-05). */
.nexus-page a.nexus-glossref,
.nexus-compose__preview a.nexus-glossref{
  color:rgb(var(--nx-text));font-weight:700;text-decoration:none;
  border-block-end:1px dashed rgb(var(--nx-accent)/.6);
}
.nexus-page a.nexus-glossref:hover,.nexus-page a.nexus-glossref:focus-visible,
.nexus-compose__preview a.nexus-glossref:hover,.nexus-compose__preview a.nexus-glossref:focus-visible{color:rgb(var(--nx-accent))}
/* The lede is the description's home on a taxonomy page, and a hovered card
   preview has to be allowed to escape it. */
.nexus-page__lede{overflow:visible}

/* --- The News composer (2026-09-05) ---------------------------------------
   The article form in the admin sandbox. It reuses .nexus-note__form,
   __field, __actions and __notice from the announcements composer above — same
   authoring surface, same look — and only adds what did not exist: the insert
   row, the one picker, the checks and the preview. Every control inside is an
   unmodified .nexus-btn. Hand-written, semantic, nothing composed at runtime. */
.nexus-compose__subhead{
  font-size:.7rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:rgb(var(--nx-muted));margin:1.75rem 0 .5rem;
}
.nexus-compose__hint{
  font-weight:600;text-transform:none;letter-spacing:0;font-size:.7rem;
  color:rgb(var(--nx-muted));margin-inline-start:.4rem;
}
/* The insert row. Wraps freely — eight buttons do not fit one line on a laptop. */
.nexus-compose__bar{
  display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;
  padding:.6rem .7rem;margin-block-end:.75rem;border-radius:.75rem;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
}
.nexus-compose__barlabel{
  font-size:.65rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:rgb(var(--nx-accent));margin-inline-end:.35rem;
}
.nexus-compose__barsep{
  inline-size:1px;block-size:1.25rem;background:rgb(var(--nx-surface-hover));margin-inline:.35rem;
}
/* The picker. A popover over the form, NOT a modal: it does not trap focus and
   it does not dim the page, because the writer is still reading the sentence
   they are about to drop a card into. */
.nexus-compose__picker{
  position:relative;margin-block-end:1rem;padding:.75rem;border-radius:.85rem;
  background:rgb(var(--nx-surface-alt));border:1px solid rgb(var(--nx-accent)/.45);
  box-shadow:0 12px 32px rgba(0,0,0,.45);
}
.nexus-compose__pickhead{display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin-block-end:.5rem}
.nexus-compose__picktitle{
  font-size:.7rem;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:rgb(var(--nx-accent));
}
.nexus-compose__picklist{
  list-style:none;padding:0;margin:.6rem 0 0;max-block-size:19rem;overflow-y:auto;
  display:flex;flex-direction:column;gap:.2rem;
}
.nexus-compose__pickitem{
  inline-size:100%;display:flex;align-items:center;gap:.65rem;text-align:start;
  padding:.4rem .5rem;border-radius:.5rem;border:1px solid transparent;
  background:transparent;color:rgb(var(--nx-text));cursor:pointer;font:inherit;
}
.nexus-compose__pickitem:hover,.nexus-compose__pickitem:focus-visible{
  background:rgb(var(--nx-surface-hover));border-color:rgb(var(--nx-accent)/.5);
}
.nexus-compose__pickitem img{
  inline-size:3.25rem;aspect-ratio:16/10;object-fit:cover;border-radius:.3rem;
  flex-shrink:0;background:rgb(var(--nx-card));
}
.nexus-compose__pickitem span{display:flex;flex-direction:column;min-inline-size:0}
.nexus-compose__pickitem b{font-size:.85rem;font-weight:800}
.nexus-compose__pickitem small{
  font-size:.7rem;color:rgb(var(--nx-muted));overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.nexus-compose__pickempty{
  font-size:.8rem;color:rgb(var(--nx-muted));padding:.5rem;list-style:none;
}
/* A source is two fields and a remove button, side by side — never nested,
   because a button may not contain another focusable control. */
.nexus-compose__source{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr) auto;
  gap:.4rem;align-items:center;margin-block-end:.4rem;
}
@media (max-width:639px){.nexus-compose__source{grid-template-columns:minmax(0,1fr) auto}}
/* The checks. Colour is a second signal, never the only one: each row states
   its finding in words, so a colour-blind reader loses nothing. */
.nexus-compose__checks{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.4rem}
.nexus-compose__check{
  padding:.55rem .75rem;border-radius:.6rem;font-size:.8rem;line-height:1.5;
  background:rgb(var(--nx-surface));border-inline-start:3px solid rgb(var(--nx-track));
}
.nexus-compose__check b{display:block;font-weight:800;color:rgb(var(--nx-text))}
.nexus-compose__check span{color:rgb(var(--nx-muted))}
.nexus-compose__check em{
  display:block;margin-block-start:.25rem;font-style:normal;font-weight:700;
  font-size:.75rem;color:rgb(var(--nx-text));
}
.nexus-compose__check--ok{border-inline-start-color:rgb(var(--nx-success))}
.nexus-compose__check--warn{border-inline-start-color:rgb(var(--nx-warning))}
.nexus-compose__check--bad{border-inline-start-color:rgb(var(--nx-error))}
/* The preview borrows .nexus-post__body wholesale, so it is the article's own
   typography; this only boxes it. */
.nexus-compose__preview{
  padding:1rem 1.25rem;border-radius:.85rem;font-size:.95rem;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
}
.nexus-compose__withpick{display:flex;gap:.4rem;align-items:center}
.nexus-compose__withpick input{flex:1 1 auto;min-inline-size:0}

/* --- The admin shell (2026-09-05) -------------------------------------------
   Chad: "can we make the admin panel a little more elegant? can we make it flow
   with the current profile options?" The answer was to stop giving Admin a
   layout of its own. It renders inside .nexus-acct now -- the account screen's
   own grid -- and every rail button is an unmodified .nexus-btn--menu, so the
   two screens are the same screen with different contents. The rules below are
   only the ones the account screen has no use for.

   WHY THE PREVIEW IS STICKY AND NOT ITS OWN SCROLLER: two scrollbars in one
   pane means the preview scrolls out of sight exactly as you reach the part of
   the form you wanted to see it react to. Sticky keeps it on screen while the
   form moves under it, and collapses to a plain block once the split stacks. */
.nexus-acct--admin{max-inline-size:96rem}
.nexus-adm__split{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,27rem);
  gap:1.5rem;align-items:start;
}
.nexus-adm__col,.nexus-adm__side{min-inline-size:0}
/* .nexus-note__form is capped at 35rem, which was the right measure when it
   was the only thing in a 48rem column. Beside a preview it is a form that
   stops halfway across its own column while the article textarea -- the one
   field that genuinely wants the room -- is the narrowest thing on screen.
   Scoped to the admin column so the bell's own forms keep the cap. */
.nexus-adm__col .nexus-note__form{max-width:none}
.nexus-adm__sticky{position:sticky;inset-block-start:0}
/* The subhead owns a 1.75rem top margin so it can separate blocks inside the
   form. As the first thing in the sticky column that margin is a misalignment,
   not a separation. */
.nexus-adm__sticky>.nexus-compose__subhead:first-child{margin-block-start:0}
@media (max-width:1180px){
  .nexus-adm__split{grid-template-columns:1fr}
  .nexus-adm__sticky{position:static}
}
/* The broadcast preview borrows the bell's own .nexus-note rows wholesale, so
   this only boxes them. */
.nexus-adm__preview{
  padding:.75rem;border-radius:.85rem;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
}
.nexus-adm__prevnote{
  margin-block-start:.5rem;font-size:.72rem;line-height:1.5;color:rgb(var(--nx-muted));
}
.nexus-adm__prevnote b{color:rgb(var(--nx-text));font-weight:700}
.nexus-adm__danger{border-color:rgb(var(--nx-error)/.35)}

/* --- The Search demand pane (2026-09-09) ------------------------------------
   Chad: "add the SEO panel to the admin dashboard please as a new side tab."

   A list of phrases with a verdict each, so it borrows .nexus-note__adminrow's
   shape rather than inventing a table: label on the left, numbers on the
   right, one row per thing you might act on. The numbers column is the only
   new idea here -- it has to hold four different units (whole-market demand,
   a week-over-week delta, OUR Google position, and how many weeks we have
   seen the phrase) without any of them reading as the same measurement, which
   is why each carries its own word or symbol rather than sitting in a column
   whose heading you have to scroll back up to find. */
.nexus-seo__summary{margin-block:.75rem}
.nexus-seo__meta{font-size:.75rem;line-height:1.6;color:rgb(var(--nx-muted))}
.nexus-seo__meta b{color:rgb(var(--nx-text));font-weight:700}
.nexus-seo__chips{display:flex;flex-wrap:wrap;gap:.4rem;margin-block-start:.6rem}
.nexus-seo__list{display:flex;flex-direction:column;gap:.35rem;margin-block-start:.75rem}
.nexus-seo__row{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.5rem .7rem;border-radius:.7rem;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
}
.nexus-seo__phrase{min-inline-size:0}
.nexus-seo__phrase b{display:block;font-weight:600;overflow-wrap:anywhere}
.nexus-seo__phrase small{
  display:block;margin-block-start:.15rem;font-size:.7rem;color:rgb(var(--nx-muted));
}
.nexus-seo__nums{
  display:flex;align-items:center;gap:.55rem;flex:0 0 auto;
  font-size:.7rem;color:rgb(var(--nx-muted));white-space:nowrap;
}
.nexus-seo__demand{font-weight:700;color:rgb(var(--nx-text))}
.nexus-seo__trend--up{color:rgb(var(--nx-success))}
.nexus-seo__trend--down{color:rgb(var(--nx-error))}
/* Striking distance -- Google already shows us, on page two or three. This is
   the cheapest work on the list, so it is the one number that is allowed to
   shout. */
.nexus-seo__pos--strike{color:rgb(var(--nx-accent));font-weight:700}
.nexus-seo__none{opacity:.7}
@media (max-width:640px){
  .nexus-seo__row{flex-direction:column;align-items:flex-start;gap:.35rem}
  .nexus-seo__nums{white-space:normal}
}

/* --- The product console (2026-09-05) --------------------------------------
   The Products section of the admin sandbox. Reuses .nexus-note__form,
   __field, __actions, __notice and __empty from the two composers above; adds
   only the tab row, the detected-wave card, the staged card list, the drop
   rows and the three read-only lists. Every control inside is an unmodified
   .nexus-btn. Hand-written, semantic, nothing composed at runtime. */
.nexus-pc__tabs{display:flex;flex-wrap:wrap;gap:.35rem;margin-block-end:1.25rem}
.nexus-pc__count{
  margin-inline-start:.4rem;padding:.05rem .4rem;border-radius:999px;
  font-size:.65rem;font-weight:900;
  background:rgb(var(--nx-warning)/.2);color:rgb(var(--nx-warning));
}
.nexus-pc__panel{min-block-size:4rem}
.nexus-pc__two{display:grid;grid-template-columns:1fr 1fr;gap:.75rem}
@media (max-width:600px){.nexus-pc__two{grid-template-columns:1fr}}

/* A wave the system found on its own. Green because it is a suggestion that
   worked, not a warning. */
.nexus-pc__wave{
  background:rgb(var(--nx-success)/.07);border:1px solid rgb(var(--nx-success)/.35);
  border-radius:.85rem;padding:.9rem 1rem;margin-block-end:.85rem;
}
.nexus-pc__found{
  display:flex;gap:.65rem;align-items:flex-start;margin:0 0 .6rem;
  font-size:.85rem;line-height:1.55;color:rgb(var(--nx-slate-300));
}
.nexus-pc__found i{color:rgb(var(--nx-success));margin-block-start:.15rem}
.nexus-pc__found b{color:rgb(var(--nx-text))}
.nexus-pc__found code{
  font-family:'Fira Code',ui-monospace,monospace;font-size:.8em;
  background:rgb(var(--nx-surface));padding:.05rem .3rem;border-radius:.25rem;
}
.nexus-pc__strip{display:flex;gap:.3rem;overflow-x:auto;padding-block:.35rem .5rem}
.nexus-pc__strip img{
  block-size:5rem;border-radius:.3rem;flex:0 0 auto;background:rgb(var(--nx-card));
}

/* The cards staged in the form. A placeholder is dimmed and dashed: it is a
   name we have not matched yet, and it must not look like a resolved card. */
.nexus-pc__cards{display:flex;flex-wrap:wrap;gap:.35rem;margin-block-end:.75rem}
.nexus-pc__card{
  display:inline-flex;align-items:center;gap:.4rem;padding:.2rem .3rem .2rem .2rem;
  border-radius:.4rem;font-size:.75rem;font-weight:700;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
}
.nexus-pc__card img{inline-size:2rem;aspect-ratio:16/10;object-fit:cover;border-radius:.25rem}
.nexus-pc__card.is-placeholder{
  border-style:dashed;border-color:rgb(var(--nx-warning)/.55);color:rgb(var(--nx-muted));
}
.nexus-pc__aside{
  display:flex;gap:.6rem;align-items:flex-start;margin:0 0 .85rem;
  font-size:.75rem;line-height:1.55;color:rgb(var(--nx-muted));
}
.nexus-pc__aside i{color:rgb(var(--nx-accent));margin-block-start:.15rem}
.nexus-pc__aside b{color:rgb(var(--nx-text))}

/* One drop, one countdown: the same row. */
.nexus-pc__drop{
  display:flex;gap:.7rem;align-items:center;padding:.6rem 0;
  border-block-end:1px solid rgb(var(--nx-surface-hover));
}
.nexus-pc__drop:last-child{border-block-end:0}
.nexus-pc__dropart{
  inline-size:2.6rem;block-size:2.6rem;border-radius:.4rem;object-fit:cover;
  flex:0 0 auto;background:rgb(var(--nx-card));
}
.nexus-pc__dropart--none{background:rgb(var(--nx-track))}
.nexus-pc__dropbody{display:flex;flex-direction:column;gap:.1rem;flex:1 1 auto;min-inline-size:0}
.nexus-pc__dropbody b{font-size:.875rem;font-weight:800}
.nexus-pc__dropbody small{font-size:.7rem;color:rgb(var(--nx-muted))}
.nexus-pc__status{
  font-size:.65rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  padding:.15rem .5rem;border-radius:999px;white-space:nowrap;flex:0 0 auto;
}
.nexus-pc__status--ok{color:rgb(var(--nx-success));background:rgb(var(--nx-success)/.14)}
.nexus-pc__status--info{color:rgb(var(--nx-accent));background:rgb(var(--nx-accent)/.14)}
.nexus-pc__status--warn{color:rgb(var(--nx-warning));background:rgb(var(--nx-warning)/.14)}
.nexus-pc__status--muted{color:rgb(var(--nx-muted));background:rgb(var(--nx-track)/.5)}

/* The spoiler queue. */
.nexus-pc__queue{margin-block-start:.85rem}
.nexus-pc__q{
  display:flex;gap:.6rem;align-items:center;padding:.5rem 0;
  border-block-end:1px solid rgb(var(--nx-surface-hover));font-size:.8rem;
}
.nexus-pc__q:last-child{border-block-end:0}
.nexus-pc__q img,.nexus-pc__qnone{
  inline-size:2.6rem;aspect-ratio:16/10;object-fit:cover;object-position:center 25%;
  border-radius:.3rem;flex:0 0 auto;background:rgb(var(--nx-card));
}
.nexus-pc__qnone{background:rgb(var(--nx-track))}
.nexus-pc__q div{display:flex;flex-direction:column;gap:.1rem;flex:1 1 auto;min-inline-size:0}
.nexus-pc__q b{font-weight:800}
.nexus-pc__q small{font-size:.7rem;color:rgb(var(--nx-muted))}

.nexus-pc__hist{list-style:none;padding:0;margin:0;font-size:.75rem;line-height:1.7}
.nexus-pc__hist li{
  padding-block:.35rem;border-block-end:1px solid rgb(var(--nx-surface-hover));
  color:rgb(var(--nx-muted));
}
.nexus-pc__hist li:last-child{border-block-end:0}
.nexus-pc__hist b{color:rgb(var(--nx-text));font-weight:800}
.nexus-pc__hist span{margin-inline-start:.4rem;font-variant-numeric:tabular-nums}

/* --- /news: the editorial surface (2026-09-05) -----------------------------
   Chad's call the same day: News is the sixth top-level nav item, not "Blog"
   and not buried under Discover. Layout only — every control inside is an
   unmodified .nexus-btn, and the card and glossary references inside an article
   reuse .nexus-cardref / .nexus-glossref above rather than inventing a second
   treatment. Hand-written, semantic, nothing composed at runtime (RULE 2). */

/* A set reference. NOT a link on purpose: there is no /sets/<code> page yet,
   and a chip that reads is better than an anchor that 404s. */
.nexus-setref{font-weight:700;color:rgb(var(--nx-text));white-space:nowrap}
.nexus-setref__when{
  margin-inline-start:.35rem;font-size:.8em;font-weight:600;color:rgb(var(--nx-muted));
}

.nexus-news__layout{display:grid;gap:2.5rem;align-items:start}
@media (min-width:1024px){.nexus-news__layout{grid-template-columns:minmax(0,1fr) minmax(16rem,20rem)}}
.nexus-news__empty{
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
  border-radius:1rem;padding:1.5rem;color:rgb(var(--nx-muted));line-height:1.6;
}
.nexus-news__empty p{margin:0 0 .75rem}
.nexus-news__empty b{color:rgb(var(--nx-text))}
.nexus-news__emptyacts{display:flex;flex-wrap:wrap;gap:.5rem;margin:1.25rem 0 0}

/* The lead. One article gets the picture; the rest get a thumbnail. */
.nexus-page a.nexus-news__lead{
  display:block;text-decoration:none;color:inherit;border-radius:1rem;overflow:hidden;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
  margin-block-end:2rem;transition:border-color .15s ease;
}
.nexus-page a.nexus-news__lead:hover,
.nexus-page a.nexus-news__lead:focus-visible{border-color:rgb(var(--nx-accent))}
.nexus-news__leadart{inline-size:100%;aspect-ratio:16/6;object-fit:cover;display:block;background:rgb(var(--nx-card))}
.nexus-news__leadbody{padding:1.25rem 1.5rem 1.5rem}
.nexus-news__leadtitle{font-size:clamp(1.25rem,2.6vw,1.85rem);font-weight:900;line-height:1.2;margin:0 0 .5rem}

.nexus-news__list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:1rem}
.nexus-page .nexus-news__item a{
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:1rem;align-items:start;
  text-decoration:none;color:inherit;padding:1rem;border-radius:1rem;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
  transition:border-color .15s ease;
}
.nexus-page .nexus-news__item a:hover,
.nexus-page .nexus-news__item a:focus-visible{border-color:rgb(var(--nx-accent))}
/* An article about a set that has come out is still true and still linked; it
   is just no longer the news. Dimmed, never hidden. */
.nexus-news__item.is-archived a{opacity:.72}
.nexus-news__item.is-archived a:hover,
.nexus-news__item.is-archived a:focus-visible{opacity:1}
.nexus-news__thumb{
  inline-size:7.5rem;aspect-ratio:16/10;object-fit:cover;display:block;border-radius:.6rem;
  background:rgb(var(--nx-card));border:1px solid rgb(var(--nx-surface-hover));
}
.nexus-news__thumb--none{background:rgb(var(--nx-track))}
.nexus-news__itembody{display:flex;flex-direction:column;gap:.35rem;min-inline-size:0}
.nexus-news__itemtitle{font-size:1.05rem;font-weight:800;line-height:1.3}
@media (max-width:539px){
  .nexus-page .nexus-news__item a{grid-template-columns:minmax(0,1fr)}
  .nexus-news__thumb{inline-size:100%;aspect-ratio:16/7}
}

.nexus-news__kicker{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;margin:0 0 .5rem}
.nexus-news__kind{
  font-size:.65rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase;
  color:rgb(var(--nx-accent));
}
.nexus-news__badge{
  font-size:.65rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  padding:.2rem .55rem;border-radius:999px;white-space:nowrap;
}
.nexus-news__badge--preview{
  color:rgb(var(--nx-warning));background:rgb(var(--nx-warning)/.12);
  border:1px solid rgb(var(--nx-warning)/.35);
}
.nexus-news__badge--out{
  color:rgb(var(--nx-success));background:rgb(var(--nx-success)/.12);
  border:1px solid rgb(var(--nx-success)/.35);
}
.nexus-news__dek{color:rgb(var(--nx-muted));line-height:1.55;margin:0}
.nexus-news__meta{
  display:flex;flex-wrap:wrap;gap:.35rem .85rem;margin:.5rem 0 0;
  font-size:.75rem;color:rgb(var(--nx-muted));font-variant-numeric:tabular-nums;
}
.nexus-news__meta span+span::before{content:"·";margin-inline-end:.85rem;color:rgb(var(--nx-track))}

.nexus-news__rail{display:flex;flex-direction:column;gap:1rem;position:sticky;top:5.5rem}
@media (max-width:1023px){.nexus-news__rail{position:static}}
.nexus-rail__box{
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
  border-radius:1rem;padding:1.1rem 1.25rem;
}
.nexus-rail__head{
  font-size:.7rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase;
  color:rgb(var(--nx-accent));margin:0 0 .75rem;
}
.nexus-rail__list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.7rem}
.nexus-rail__list li{display:flex;flex-direction:column;gap:.1rem}
.nexus-rail__list b{font-size:.9rem;font-weight:800}
.nexus-rail__list span{font-size:.75rem;color:rgb(var(--nx-muted));font-variant-numeric:tabular-nums}
.nexus-rail__foot{font-size:.7rem;color:rgb(var(--nx-muted));line-height:1.5;margin:.85rem 0 0}
.nexus-rail__copy{font-size:.85rem;color:rgb(var(--nx-muted));line-height:1.55;margin:0 0 .85rem}

/* --- one article --------------------------------------------------------- */
.nexus-post{max-inline-size:46rem}
.nexus-post .nexus-page__art--wide{aspect-ratio:16/6;margin-block-end:1.75rem}
.nexus-post__byline{
  display:flex;flex-wrap:wrap;gap:.35rem .85rem;font-size:.8rem;color:rgb(var(--nx-muted));
  margin:0 0 1.5rem;
}
.nexus-post__byline span+span::before{content:"·";margin-inline-end:.85rem;color:rgb(var(--nx-track))}
/* We warn, we do not hide. An article written mid-spoiler-season says so, and
   stops saying so on release day because is_preview is computed at read time. */
.nexus-post__warn,.nexus-post__out{
  display:flex;gap:.75rem;align-items:flex-start;line-height:1.55;
  border-radius:.85rem;padding:.85rem 1rem;margin:0 0 1.75rem;font-size:.9rem;
}
.nexus-post__warn{
  color:rgb(var(--nx-text));background:rgb(var(--nx-warning)/.1);
  border:1px solid rgb(var(--nx-warning)/.4);
}
.nexus-post__warn i{color:rgb(var(--nx-warning));margin-block-start:.15rem}
.nexus-post__out{
  color:rgb(var(--nx-text));background:rgb(var(--nx-success)/.1);
  border:1px solid rgb(var(--nx-success)/.35);
}
.nexus-post__out i{color:rgb(var(--nx-success));margin-block-start:.15rem}

.nexus-post__body{font-size:1.03rem;line-height:1.75;overflow:visible}
.nexus-post__body p{margin:0 0 1.15rem}
.nexus-post__body h2{font-size:1.4rem;font-weight:900;line-height:1.25;margin:2.25rem 0 .85rem}
.nexus-post__body ul{margin:0 0 1.15rem;padding-inline-start:1.25rem}
.nexus-post__body li{margin-block-end:.45rem}
.nexus-post__body blockquote{
  margin:0 0 1.15rem;padding:.75rem 1.1rem;border-inline-start:3px solid rgb(var(--nx-accent));
  background:rgb(var(--nx-surface));border-radius:0 .6rem .6rem 0;color:rgb(var(--nx-slate-300));
}

/* Chad asked for real citations he can paste. They are stored per post and
   printed verbatim; nothing here is generated. */
.nexus-sources ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.5rem}
.nexus-sources li{font-size:.9rem;line-height:1.5}
.nexus-sources__fan{
  font-family:'Fira Code',ui-monospace,monospace;font-size:.7rem;line-height:1.6;
  color:rgb(var(--nx-muted));margin:1.25rem 0 0;max-inline-size:60ch;
}
.nexus-post__back{margin-block-start:2.5rem}

.nexus-glossary{padding:0;margin:0;list-style:none}
.nexus-glossary > div{padding:1rem 0;border-block-end:1px solid rgb(var(--nx-surface-hover))}
.nexus-glossary dt,.nexus-glossary b{font-weight:800;font-size:1.05rem}
.nexus-glossary p{margin:.35rem 0 0;color:rgb(var(--nx-slate-300));line-height:1.6}
.nexus-bracket{background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));border-radius:1rem;padding:1.25rem 1.5rem;margin-block-end:1rem}
.nexus-bracket h2{margin:0 0 .25rem;font-size:1.2rem}
.nexus-bracket .nexus-bracket__range{font-size:.75rem;color:rgb(var(--nx-accent));letter-spacing:.1em;text-transform:uppercase}
.nexus-bracket ul{margin:.75rem 0 0;padding-inline-start:1.2rem;color:rgb(var(--nx-slate-300));line-height:1.6}
.nexus-bracket .nexus-rule--no{color:rgb(var(--nx-error-lit))}
.nexus-bracket .nexus-rule--yes{color:rgb(var(--nx-success-lit))}
.nexus-legal{max-inline-size:70ch;line-height:1.65;color:rgb(var(--nx-slate-300))}
.nexus-legal h2{color:rgb(var(--nx-text));margin:1.25rem 0 .25rem}
.nexus-legal ul{padding-inline-start:1.25rem}
.nexus-legal a{color:rgb(var(--nx-violet-lit))}
/* Content-page callout (the "what this term means" aside on precon, commander
   and taxonomy pages). Was .nexus-note until 2026-09-03, when the notifications
   panel took that name with display:flex: a <p> with an inline link then laid
   out as three flex items and read "The [brackets page] explains the scale"
   in three columns. Distinct name, no shared rules. */
.nexus-callout{font-size:.8rem;color:rgb(var(--nx-muted));border-inline-start:3px solid rgb(var(--nx-violet));padding-inline-start:.75rem;margin:1rem 0}


/* ==========================================================================
   NOTIFICATIONS — the bell, the announcement panel, the changelog rows and
   the stale-tab prompt. Added 2026-09-03, from the approved mockup
   (mockups/notifications-system.html).

   Written per THE RULES at the top of this file: every class here has a real
   rule, the names are semantic, and NOTHING is composed at runtime — the four
   `kind` values map to literal class strings in a lookup table in
   src/scripts/modules/25-notifications.js.

   No bespoke button CSS: every control in this feature is .nexus-btn plus a
   size, an emphasis and a tone, exactly as the button header above requires.
   The only genuinely new visual primitive in the whole system is
   .nexus-bell-badge.
   ========================================================================== */

/* --- the badge on the bell ------------------------------------------------ */
.nexus-bell-host{position:relative;display:inline-flex}
.nexus-bell-badge{position:absolute;top:-4px;right:-4px;min-width:16px;height:16px;padding:0 4px;
    border-radius:9999px;background:rgb(var(--nx-accent));color:rgb(var(--nx-base));font-size:10px;font-weight:800;
    line-height:16px;text-align:center;border:2px solid rgb(var(--nx-surface));pointer-events:none}

/* --- the dropdown panel --------------------------------------------------- */
.nexus-note__panel{position:absolute;top:calc(100% + .6rem);right:0;z-index:60;width:392px;
    max-width:calc(100vw - 2rem);border-radius:.8rem;overflow:hidden;background:rgb(var(--nx-surface)/.98);
    border:1px solid rgb(var(--nx-track));box-shadow:0 24px 60px rgba(0,0,0,.65)}
.nexus-note__head{display:flex;align-items:center;justify-content:space-between;gap:1rem;
    padding:.85rem 1rem;border-bottom:1px solid rgb(var(--nx-surface-hover))}
.nexus-note__paneltitle{font-family:Outfit,sans-serif;font-weight:900;font-size:.9375rem;color:rgb(var(--nx-slate-200))}
.nexus-note__list{max-height:min(70vh,540px);overflow-y:auto}
.nexus-note__foot{padding:.7rem 1rem;border-top:1px solid rgb(var(--nx-surface-hover));text-align:center}
.nexus-note__foot a{color:rgb(var(--nx-accent));font-size:.75rem;font-weight:700;text-decoration:none}
.nexus-note__foot a:hover{text-decoration:underline}

/* --- THE WATERMARK LINE ---------------------------------------------------
   Everything above it is new; everything below it has been seen. It is the
   entire read model made visible, and it can only ever appear in one place. */
.nexus-note__seenline{display:flex;align-items:center;gap:.6rem;padding:.4rem 1rem;
    background:rgb(var(--nx-accent)/.05)}
.nexus-note__seenline::before,
.nexus-note__seenline::after{content:"";height:1px;flex:1;background:rgb(var(--nx-accent)/.28)}
.nexus-note__seenline span{font-family:'Fira Code',monospace;font-size:.5625rem;font-weight:700;
    letter-spacing:.09em;text-transform:uppercase;color:rgb(var(--nx-accent));white-space:nowrap}

/* --- one announcement ----------------------------------------------------- */
.nexus-note{display:flex;gap:.8rem;padding:.85rem 1rem;border-bottom:1px solid rgb(var(--nx-surface-hover)/.7);
    text-align:left}
.nexus-note:last-child{border-bottom:0}
.nexus-note--unread{background:rgb(var(--nx-accent)/.035)}
.nexus-note__body{min-width:0}
.nexus-note__ico{width:26px;height:26px;flex:0 0 26px;border-radius:.45rem;display:grid;
    place-items:center;font-size:.6875rem;margin-top:.1rem}
.nexus-note__ico--feature{background:rgb(var(--nx-violet)/.16);color:rgb(var(--nx-violet-lit));border:1px solid rgb(var(--nx-violet)/.4)}
.nexus-note__ico--fix{background:rgb(var(--nx-success)/.16);color:rgb(var(--nx-success-lit));border:1px solid rgb(var(--nx-success)/.45)}
.nexus-note__ico--known{background:rgb(var(--nx-warning)/.16);color:rgb(var(--nx-rare));border:1px solid rgb(var(--nx-warning)/.45)}
.nexus-note__ico--news{background:rgb(var(--nx-accent)/.14);color:rgb(var(--nx-accent));border:1px solid rgb(var(--nx-accent)/.4)}
.nexus-note__title{margin:0 0 .2rem;font-size:.8125rem;font-weight:700;color:rgb(var(--nx-slate-200));line-height:1.35}
.nexus-note__text{margin:0;font-size:.75rem;color:rgb(var(--nx-muted));line-height:1.5;overflow-wrap:anywhere}
.nexus-note__when{margin:.35rem 0 0;font-family:'Fira Code',monospace;font-size:.625rem;color:rgb(var(--nx-slate-500))}
.nexus-note__link{display:inline-block;margin-top:.35rem;font-size:.75rem;font-weight:700;
    color:rgb(var(--nx-accent));text-decoration:none}
.nexus-note__link:hover{text-decoration:underline}
.nexus-note__empty{margin:0;padding:1.4rem 1rem;font-size:.8125rem;color:rgb(var(--nx-muted));text-align:center;
    line-height:1.55}

/* --- kind chips ----------------------------------------------------------- */
.nexus-note__chip{display:inline-block;font-family:'Fira Code',monospace;font-size:.5625rem;
    font-weight:700;letter-spacing:.07em;text-transform:uppercase;padding:.05rem .35rem;
    border-radius:.25rem;margin-left:.4rem;vertical-align:1px}
/* Each ink is pulled toward the page text, as .nexus-front__kind is: the pure
   inks failed AA on their own wash in the light theme (fix 3.83, known 3.46,
   news 3.69 on green), measured by axe-core 2026-09-10. */
.nexus-note__chip--feature{background:rgb(var(--nx-violet)/.2);color:color-mix(in srgb,rgb(var(--nx-violet-lit)) 80%,rgb(var(--nx-text)))}
.nexus-note__chip--fix{background:rgb(var(--nx-success)/.2);color:color-mix(in srgb,rgb(var(--nx-success-lit)) 80%,rgb(var(--nx-text)))}
.nexus-note__chip--known{background:rgb(var(--nx-warning)/.2);color:color-mix(in srgb,rgb(var(--nx-rare)) 80%,rgb(var(--nx-text)))}
.nexus-note__chip--news{background:rgb(var(--nx-accent)/.16);color:color-mix(in srgb,rgb(var(--nx-accent)) 80%,rgb(var(--nx-text)))}

/* --- the stale-tab prompt -------------------------------------------------
   Sits under the header, full width. NEVER a modal: a user mid-way through
   building a deck has to be able to ignore it and keep working. */
/* No auto margins here. #nexus-app-shell is a COLUMN flex container, and an
   auto inline margin on a flex item disables align-items:stretch — the bar
   shrank to its content (843px measured) and sat left of centre instead of
   lining up with the header. Alignment is the wrapper's job: the markup puts
   this inside the same `max-w-7xl mx-auto px-5` container the header uses. */
.nexus-refresh-bar{display:flex;align-items:center;gap:.9rem;flex-wrap:wrap;
    margin:.75rem 0 0;padding:.75rem 1.1rem;border-radius:.6rem;
    background:rgb(var(--nx-violet)/.12);border:1px solid rgb(var(--nx-violet)/.45)}
.nexus-refresh-bar__ico{width:30px;height:30px;flex:0 0 30px;border-radius:9999px;display:grid;
    place-items:center;background:rgb(var(--nx-violet)/.25);color:rgb(var(--nx-violet-lit));font-size:.8125rem}
.nexus-refresh-bar__text{flex:1;min-width:12rem}
.nexus-refresh-bar__text strong{display:block;font-size:.8125rem;color:rgb(var(--nx-slate-200));font-weight:700}
.nexus-refresh-bar__text small{display:block;font-size:.75rem;color:#a5b4cf;margin-top:.1rem;
    line-height:1.45}

/* --- /changelog ----------------------------------------------------------- */
.nexus-note__log{max-width:44rem;margin:0 auto}
.nexus-note__day{font-family:'Fira Code',monospace;font-size:.6875rem;font-weight:700;
    letter-spacing:.09em;text-transform:uppercase;color:rgb(var(--nx-muted));padding:1.4rem 0 .5rem;
    border-bottom:1px solid rgb(var(--nx-surface-hover));margin:0 0 .3rem}
.nexus-note__day:first-child{padding-top:0}
.nexus-note__log .nexus-note{border-bottom:0;padding-left:0;padding-right:0;background:none}

/* --- the compose form ----------------------------------------------------- */
.nexus-note__form{max-width:35rem;display:grid;gap:.85rem}
.nexus-note__field label{display:block;font-size:.6875rem;font-weight:700;letter-spacing:.07em;
    text-transform:uppercase;color:rgb(var(--nx-muted));margin-bottom:.3rem;font-family:'Fira Code',monospace}
.nexus-note__field input,
.nexus-note__field textarea,
.nexus-note__field select{width:100%;padding:.55rem .7rem;border-radius:.45rem;background:rgb(var(--nx-base));
    border:1px solid rgb(var(--nx-track));color:rgb(var(--nx-slate-200));font-family:inherit;font-size:.8125rem}
.nexus-note__field textarea{min-height:4.75rem;resize:vertical;line-height:1.5}
.nexus-note__actions{display:flex;gap:.6rem;align-items:center;flex-wrap:wrap;padding-top:.3rem}
.nexus-note__notice{margin:0;font-size:.75rem;color:rgb(var(--nx-success-lit));line-height:1.5}
.nexus-note__notice--bad{color:rgb(var(--nx-error-lit))}
/* A refusal to act is not a success. There is no --nx-warning-lit, and adding a
   theme variable for one line would be a system change; --nx-warning reads
   clearly on both the dark panel and the light one. */
.nexus-note__notice--warn{color:rgb(var(--nx-warning))}
.nexus-note__adminrow{display:flex;align-items:flex-start;gap:.6rem;
    border-bottom:1px solid rgb(var(--nx-surface-hover)/.7)}
.nexus-note__adminrow .nexus-note{flex:1;border-bottom:0}
.nexus-note__adminrow > .nexus-btn{margin:.85rem .5rem 0 0}

/* --- a row that carries MORE than one verb (2026-09-09, revised 2026-09-10)
   The news list grew Take off site / Put back / Delete beside Edit. Three
   buttons as direct children of the row compete with the headline for width,
   and at 1048px the labels wrapped mid-phrase ("TAKE IT OFF THE / SITE")
   while the title squeezed to two lines. So the row splits properly: the
   description takes the space it needs and the verbs sit together on the
   right, wrapping as a group instead of individually.
   No button styling here -- the buttons stay plain .nexus-btn and this owns
   only where they sit. The 09-09 version also set white-space:nowrap on them,
   which the BUTTONS block forbids ("buttons must be allowed to wrap at 320px
   rather than force horizontal overflow"); the labels are short enough now
   that it bought nothing, so it is gone. */
/* Only the rows that HAVE a verb group wrap: the announcement list shares
   .nexus-note__adminrow and its single Edit never needs to. Measured at
   412px -- without this the description shrank to 99px and the headline
   stacked five lines deep beside three buttons it could not fit next to. */
.nexus-note__adminrow--acts{flex-wrap:wrap}
.nexus-note__adminwhat{flex:1 1 14rem;min-width:0}
/* The verbs never shrink. They are the smallest thing in the row and the
   only one that cannot reflow, so the description absorbs the squeeze and
   the group drops to its own line when there is genuinely no room. */
.nexus-note__adminacts{display:flex;flex-wrap:wrap;align-items:flex-start;
    flex:0 0 auto;gap:.4rem;margin:.85rem 0 .6rem auto}
.nexus-note__adminacts > .nexus-btn{margin:0}

/* --- the pending queue (2026-09-03) ---------------------------------------
   Drafts waiting to go out, in the order they will go out in. Rules per THE
   RULES #1: every class here is real and named for what it is. The grip is a
   plain .nexus-btn--icon and gets NO button styling of its own; the grab
   cursor sits on the ROW, which is the thing that is actually draggable. */
.nexus-note__queuehead{display:flex;align-items:center;justify-content:space-between;gap:.75rem;
    flex-wrap:wrap;padding:.6rem .25rem;border-bottom:1px solid rgb(var(--nx-surface-hover)/.7)}
.nexus-note__queuehead span{font-family:'Fira Code',monospace;font-size:.5625rem;font-weight:700;
    letter-spacing:.09em;text-transform:uppercase;color:rgb(var(--nx-muted))}
.nexus-note__adminrow--pending{cursor:grab;background:rgb(var(--nx-warning)/.05)}
.nexus-note__adminrow--pending:active{cursor:grabbing}
/* The row being carried, and the row it would land on. Two different states,
   so they read differently at a glance: the source fades, the target grows an
   accent edge where the row would land. */
.nexus-note__adminrow--dragging{opacity:.45}
.nexus-note__adminrow--over{box-shadow:inset 0 2px 0 0 rgb(var(--nx-accent));
    background:rgb(var(--nx-accent)/.08)}

/* ==========================================================================
   THE LANDING HERO'S ART — added 2026-09-05.

   WHY THIS IS HAND-WRITTEN NOW. The art column and the card inside it were
   sized by ex-Tailwind classes, and only some of them survive: `h-[28rem]` has
   a rule in components.css, `h-[450px]` never did. So the COLUMN had no height
   at all, the card inside it is absolutely positioned, and the column therefore
   collapsed to nothing — the hero's height came entirely from its own padding,
   and the card floated out of the section into it. That worked by accident
   while the padding was 224px. It stopped working the moment the front-page
   feed made a shorter hero worth having, because the card had nothing left to
   overflow into and slid up under the header.

   Measured before changing anything: section 336px tall, card 462px tall
   starting 59px ABOVE the section's own top edge.

   These two rules give the column a real height and the card a real size, so
   the section is as tall as what is in it. The card is smaller than it was —
   the hero is no longer the only thing on the page, and it no longer needs to
   fill a screen on its own.
   ========================================================================== */
.nexus-hero__art{block-size:23rem}
.nexus-hero__card{inline-size:13.5rem;block-size:20.5rem}
@media (min-width:1024px){
  .nexus-hero__art{block-size:25rem}
  .nexus-hero__card{inline-size:15rem;block-size:22.5rem}
}

/* ==========================================================================
   THE FRONT PAGE'S LIVING HALF — added 2026-09-05.
   Sits between the hero and the written landing page, inside
   #public-landing-view, so the app hides it with the hero the moment a deck
   opens. See src/components/views/LandingFeed.astro for what it shows and why.

   Written per THE RULES at the top of this file: every class has a real rule,
   the names are semantic, nothing is composed at runtime, and there is not one
   ex-Tailwind utility in the markup — this block is the whole of its styling.

   No bespoke button CSS, because this section has no buttons. The lead article
   and each list row are single <a> elements wrapping their own contents, which
   is what makes the whole card a click target without nesting a control inside
   one (RULE 3 above .nexus-btn: a button may never contain another focusable
   control, and a link that swallows a second link is the same mistake).
   ========================================================================== */
.nexus-front{
  inline-size:100%;padding-block:2.5rem 0;
}
.nexus-front__inner{max-inline-size:80rem;margin-inline:auto;padding-inline:1.5rem}
.nexus-front__block+.nexus-front__block{margin-block-start:2.75rem}
.nexus-front__head{
  display:flex;align-items:baseline;gap:.75rem;flex-wrap:wrap;margin-block-end:.9rem;
}
.nexus-front__h{
  font-family:Outfit,ui-sans-serif,system-ui,sans-serif;font-weight:900;
  font-size:1.375rem;letter-spacing:-.02em;color:rgb(var(--nx-text));margin:0;
}
.nexus-front__more{
  margin-inline-start:auto;font-size:.8125rem;font-weight:700;
  color:rgb(var(--nx-accent));text-decoration:none;
}
.nexus-front__more:hover,.nexus-front__more:focus-visible{text-decoration:underline}
.nexus-front__lede{
  font-size:.875rem;line-height:1.6;color:rgb(var(--nx-muted));
  max-inline-size:70ch;margin:-.35rem 0 1rem;
}

/* The small labels. Two tones and no third: an editorial kind is the accent,
   everything neutral is quiet, and the only warning colour on the page is the
   one that says a card cannot legally be played yet. */
.nexus-front__tags{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-block-end:.45rem}
.nexus-front__kind,.nexus-front__kindq,.nexus-front__warn{
  font-size:.625rem;font-weight:800;letter-spacing:.09em;text-transform:uppercase;
  padding:.15rem .45rem;border-radius:.3rem;flex:none;
}
/* The ink is the accent pulled 20% toward the page text: darker in the light
   theme, lighter in the dark one, so it always gains contrast on its own tint.
   Pure accent failed AA in 5 of the 12 theme x accent pairs (PageSpeed flagged
   "NEXT UP" at 4.43:1 on the light cyan; green/gold light 4.08, dark ruby
   4.47); at 20% the worst pair is 5.45:1. Computed 2026-09-10. */
.nexus-front__kind{background:rgb(var(--nx-accent)/.14);color:color-mix(in srgb,rgb(var(--nx-accent)) 80%,rgb(var(--nx-text)))}
.nexus-front__kindq{background:rgb(var(--nx-muted)/.16);color:rgb(var(--nx-muted))}
.nexus-front__warn{background:rgb(var(--nx-warning)/.18);color:rgb(var(--nx-rare))}
.nexus-front__meta{
  font-size:.75rem;line-height:1.5;color:rgb(var(--nx-muted));display:block;
}
.nexus-front__dek{
  font-size:.875rem;line-height:1.6;color:rgb(var(--nx-slate-300));
  display:block;margin-block:.35rem .5rem;
}
.nexus-front__note{
  font-size:.6875rem;line-height:1.5;color:rgb(var(--nx-muted));margin-block-start:.6rem;
}

/* --- Latest --------------------------------------------------------------- */
.nexus-front__news{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:1.25rem}
/* One article and no others. Left alone the lead sat in a 1.35fr column with
   an empty 1fr beside it, which reads as a page that failed to load rather
   than a page with one article on it. Solo, it turns on its side: art left,
   words right, full width. */
.nexus-front__news--solo{grid-template-columns:1fr}
.nexus-front__news--solo .nexus-front__lead{
  grid-template-columns:minmax(0,22rem) minmax(0,1fr);grid-template-rows:auto;
  align-items:center;gap:1.25rem;
}
.nexus-front__news--solo .nexus-front__leadart img{aspect-ratio:16/9}
@media (max-width:760px){
  .nexus-front__news--solo .nexus-front__lead{grid-template-columns:1fr}
}
.nexus-front__lead{
  display:grid;grid-template-rows:auto 1fr;gap:.85rem;text-decoration:none;color:inherit;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
  border-radius:1rem;padding:.85rem;overflow:hidden;
}
.nexus-front__lead:hover,.nexus-front__lead:focus-visible{border-color:rgb(var(--nx-accent)/.55)}
.nexus-front__leadart{display:block;border-radius:.7rem;overflow:hidden;background:rgb(var(--nx-card))}
.nexus-front__leadart img{
  display:block;inline-size:100%;aspect-ratio:16/7;object-fit:cover;object-position:center 30%;
}
.nexus-front__leadtext{display:block;padding-inline:.35rem;padding-block-end:.35rem}
.nexus-front__leadtitle{
  font-family:Outfit,ui-sans-serif,system-ui,sans-serif;font-weight:900;
  font-size:1.25rem;line-height:1.25;letter-spacing:-.015em;color:rgb(var(--nx-text));display:block;
}
.nexus-front__list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.6rem}
.nexus-front__list a{
  display:block;text-decoration:none;color:inherit;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
  border-radius:.75rem;padding:.7rem .85rem;
}
.nexus-front__list a:hover,.nexus-front__list a:focus-visible{border-color:rgb(var(--nx-accent)/.55)}
.nexus-front__list strong{
  display:block;font-size:.9375rem;font-weight:800;line-height:1.35;
  color:rgb(var(--nx-text));margin-block:.35rem .3rem;
}

/* --- Coming next ---------------------------------------------------------- */
.nexus-front__cds{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.85rem}
.nexus-front__cd{
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
  border-radius:.85rem;padding:.9rem;
}
.nexus-front__cd--lead{border-color:rgb(var(--nx-accent)/.4)}
.nexus-front__cdtop{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-block-end:.55rem}
.nexus-front__cdtop .nexus-front__meta{margin-inline-start:auto}
.nexus-front__cdn{display:flex;align-items:baseline;gap:.4rem;margin-block-end:.35rem}
.nexus-front__cdn b{
  font-family:Outfit,ui-sans-serif,system-ui,sans-serif;font-weight:900;
  font-size:2rem;line-height:1;letter-spacing:-.03em;color:rgb(var(--nx-text));
}
.nexus-front__cdn span{
  font-size:.65rem;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:rgb(var(--nx-muted));
}
.nexus-front__cdname{display:block;font-size:.9375rem;font-weight:800;line-height:1.3;color:rgb(var(--nx-text))}
.nexus-front__cdname+.nexus-front__meta{margin-block-start:.25rem}

/* --- On sale now ---------------------------------------------------------- */
.nexus-front__drop{
  display:grid;grid-template-columns:14rem minmax(0,1fr);gap:1.25rem;align-items:center;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
  border-radius:1rem;padding:1.1rem;
}
.nexus-front__drop+.nexus-front__drop{margin-block-start:.85rem}
/* The fan. Three cards, overlapped and tilted, because a drop is a physical
   product and a flat row of thumbnails does not read as one. */
.nexus-front__fan{position:relative;block-size:10.5rem}
.nexus-front__fan img{
  position:absolute;inline-size:6.9rem;block-size:auto;border-radius:.4rem;
  box-shadow:0 8px 20px rgb(0 0 0/.55);inset-block-start:.9rem;
}
.nexus-front__fan img[data-fan="0"]{inset-inline-start:0;transform:rotate(-8deg)}
.nexus-front__fan img[data-fan="1"]{inset-inline-start:2.75rem;inset-block-start:.35rem;transform:rotate(-1deg)}
.nexus-front__fan img[data-fan="2"]{inset-inline-start:5.5rem;transform:rotate(7deg)}
.nexus-front__fanflat{position:static;inline-size:100%;transform:none;inset:auto}
.nexus-front__dropname{
  font-family:Outfit,ui-sans-serif,system-ui,sans-serif;font-weight:900;
  font-size:1.125rem;line-height:1.25;color:rgb(var(--nx-text));display:block;
}

/* --- Not out yet ---------------------------------------------------------- */
.nexus-front__strip{
  list-style:none;padding:0 0 .4rem;margin:0;display:flex;gap:.6rem;overflow-x:auto;
}
.nexus-front__pv{
  flex:0 0 9.5rem;background:rgb(var(--nx-surface));
  border:1px solid rgb(var(--nx-surface-hover));border-radius:.6rem;padding:.5rem;
}
/* width/height on these <img>s (488x680, every Scryfall card image's shape)
   only reserve the box before the art arrives; block-size:auto keeps the
   height attribute from ever sizing the picture itself. */
.nexus-front__pv img{display:block;inline-size:100%;block-size:auto;border-radius:.4rem;margin-block-end:.4rem}
.nexus-front__pvn{
  display:block;font-size:.6875rem;font-weight:800;line-height:1.3;
  color:rgb(var(--nx-text));margin-block-end:.25rem;
}

@media (max-width:900px){
  .nexus-front__news{grid-template-columns:1fr}
  .nexus-front__cds{grid-template-columns:1fr}
  .nexus-front__drop{grid-template-columns:1fr}
  .nexus-front__fan{block-size:9rem;max-inline-size:14rem}
}

/* ==========================================================================
   THE WRITTEN LANDING PAGE — added 2026-09-02.
   Renders on "/" only, below the hero and inside #public-landing-view, so the
   app hides it along with the hero when a deck opens. See
   src/components/views/LandingIntro.astro for why it exists.

   Written per THE RULES at the top of this file: every class here has a real
   rule, all names are semantic, nothing is composed at runtime. The markup uses
   NO ex-Tailwind utilities at all — this block is the whole of its styling —
   so there is no way for it to depend on a utility that a later pass strips.

   No bespoke button CSS: this section has no buttons. Its links are prose
   links, coloured here the same way .nexus-page colours the ones on the public
   content pages, so a link reads identically on both sides of the site.
   ========================================================================== */
.nexus-lander{
  inline-size:100%;border-block-start:1px solid rgb(var(--nx-surface-hover));
  background:linear-gradient(180deg,rgb(var(--nx-base)/0) 0%,rgb(var(--nx-base)) 12%,rgb(var(--nx-base)) 100%);
  padding-block:3.5rem 4.5rem;
}
.nexus-lander__inner{max-inline-size:80rem;margin-inline:auto;padding-inline:1.5rem}
.nexus-lander__block+.nexus-lander__block{margin-block-start:3.25rem}
.nexus-lander__h{
  font-family:Outfit,ui-sans-serif,system-ui,sans-serif;
  font-size:clamp(1.35rem,2.6vw,1.9rem);font-weight:900;line-height:1.15;
  letter-spacing:-.015em;color:rgb(var(--nx-text));margin:0 0 1rem;
}
.nexus-lander__p{
  font-size:1rem;line-height:1.7;color:rgb(var(--nx-slate-300));max-inline-size:68ch;margin:0 0 1rem;
}
.nexus-lander__p:last-child{margin-block-end:0}
/* The format explainer runs in two columns from 1024px up. One column at a
   68ch measure left the right half of a desktop screen empty; two keeps the
   measure readable and fills the block. Below 1024px it is a single column. */
@media (min-width:1024px){
  .nexus-lander__cols{columns:2;column-gap:3rem}
  .nexus-lander__cols .nexus-lander__p{break-inside:avoid;max-inline-size:none}
}
.nexus-lander__p b{color:rgb(var(--nx-text));font-weight:800}
.nexus-lander__sub{font-size:.875rem;line-height:1.6;color:rgb(var(--nx-muted));max-inline-size:68ch;margin:-.35rem 0 1.25rem}
.nexus-lander a{color:rgb(var(--nx-accent));text-decoration:underline;text-underline-offset:.15em}
.nexus-lander a:hover,.nexus-lander a:focus-visible{color:#7DD3FC}

/* The three panels. Same surface, border and radius as .nexus-bracket so a
   panel here and a bracket card on /brackets are visibly the same object. */
.nexus-lander__grid{display:grid;gap:1rem;grid-template-columns:1fr}
@media (min-width:768px){.nexus-lander__grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
.nexus-lander__panel{background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));border-radius:1rem;padding:1.25rem 1.5rem}
.nexus-lander__panelh{
  font-family:Outfit,ui-sans-serif,system-ui,sans-serif;
  font-size:1.0625rem;font-weight:800;line-height:1.25;color:rgb(var(--nx-text));margin:0 0 .6rem;
}
.nexus-lander__panel .nexus-lander__p{font-size:.9375rem;max-inline-size:none}

/* The trending names: a wrapping row, each name its own target. */
.nexus-lander__names{display:flex;flex-wrap:wrap;gap:.5rem;list-style:none;padding:0;margin:0}
.nexus-lander__names a{
  display:inline-block;background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));border-radius:999px;
  padding:.4rem .9rem;font-size:.8125rem;font-weight:700;color:rgb(var(--nx-text));text-decoration:none;
}
.nexus-lander__names a:hover,.nexus-lander__names a:focus-visible{border-color:rgb(var(--nx-accent));color:rgb(var(--nx-accent))}

/* "Or start somewhere else": a real list, because each line is a definition as
   much as a link. columns, not a grid, so a long line wraps inside its column. */
.nexus-lander__start{
  columns:26rem;column-gap:2.5rem;list-style:none;padding:0;margin:0;
  font-size:.9375rem;line-height:1.65;color:rgb(var(--nx-muted));
}
.nexus-lander__start li{break-inside:avoid;margin-block-end:.7rem}
.nexus-lander__start a{font-weight:700}

/* --- push toggle, inside the bell panel -----------------------------------
   Sits ABOVE the list, under the panel header (moved there 2026-09-03: a
   browser will not let notifications be on by default, so the ask has to be
   somewhere it gets read). Its own bottom border rather than a top border on
   the list, so it disappears cleanly when hidden for a guest and leaves no
   stray rule behind. */
.nexus-note__push{
  display:flex;align-items:center;gap:.75rem;justify-content:flex-end;
  flex-wrap:wrap;
  padding:.75rem 1rem;border-bottom:1px solid rgb(var(--nx-surface-hover)/.7);
  background:rgb(var(--nx-violet)/.05);
}
/* The un-answered ask. Louder than the settled state — once "Turn on" or
   "Not now" has been clicked this modifier comes off and the row goes back to
   being a quiet toggle, because it must stay reachable either way. */
.nexus-note__push--prompt{background:rgb(var(--nx-violet)/.13);
  box-shadow:inset 3px 0 0 0 rgb(var(--nx-violet))}
.nexus-note__push--prompt .nexus-note__push-label{color:rgb(var(--nx-slate-200))}
/* The label takes the row and the two buttons travel together in their own box.
   Measured 2026-09-03 in the real 392px panel: with the buttons as loose flex
   children, "Turn on" stayed on the sentence's line and "Not now" fell to a
   line of its own, reading as two unrelated controls. */
.nexus-note__push-label{font-size:.75rem;line-height:1.35;color:rgb(var(--nx-muted));
    flex:1 1 12rem;min-width:0;margin-inline-end:auto}
.nexus-note__push-actions{display:inline-flex;align-items:center;gap:.4rem;flex:0 0 auto}
/* The label may wrap; the button may not. Without this the flex row shrinks
   the button instead of the sentence and "Turn on" breaks across two lines
   (seen 2026-09-03). This is flex-child layout inside the row, not button
   styling — the button keeps its .nexus-btn modifiers and nothing else. */
.nexus-note__push > .nexus-btn{flex:0 0 auto}

/* `.hidden{display:none}` is a Tailwind utility declared near the top of this
   file (line ~417). Any hand-written block BELOW it that sets `display:` has
   the same specificity and therefore WINS, so an element toggled with
   classList.add('hidden') keeps rendering. Both of these are toggled that way.
   Measured live 2026-09-03, guest, empty localStorage:
   {"nexus-refresh-bar":{"classes":"nexus-refresh-bar hidden","display":"flex",
   "visible":true}} -- every first-time visitor was reading "A newer version of
   Commander Nexus is ready" on the landing page. Any future component styled
   below the utilities and hidden by class needs the same guard. */
.nexus-refresh-bar.hidden,
.nexus-note__push.hidden{display:none}

/* ==========================================================================
   ON-COLOUR TEXT — companion to the COLOUR TOKENS block (2026-09-03).
   .text-white resolves to --nx-ink, which is dark in the light theme. An
   element whose OWN background is a solid brand or semantic fill re-declares
   the ink on itself, so its label stays white in both themes. The selectors
   are the exact utility classes the markup puts on badges, chips and the
   OAuth buttons; add to the list, never to the token.
   ========================================================================== */
.bg-nexus-error,.bg-nexus-error\/90,.bg-nexus-blue\/90,.bg-nexus-success,.bg-nexus-violet,
.bg-nexus-warning\/90,.bg-brand-discord,.nexus-btn--oauth{--nx-ink:255 255 255}

/* ==========================================================================
   RARITY ROW — card details modal (2026-09-03, Chad approved). Sits under
   the type line and explains, in a day-one player's words, the one thing the
   tile border colour has meant all along: how often the card gets printed.
   Six rarities: special and bonus were unmapped before today, so 401 cards
   (measured live 2026-09-02) rendered with the grey common border.
   ========================================================================== */
.nexus-rarity{display:flex;flex-wrap:wrap;align-items:center;gap:.625rem;margin-block-end:.75rem}
.nexus-rarity.hidden{display:none}
.nexus-rarity__gem{--gem:var(--nx-common);flex:none;inline-size:1.5rem;block-size:1.5rem;
  border-radius:.375rem;display:grid;place-items:center;
  font-family:Outfit,ui-sans-serif,system-ui,sans-serif;font-weight:900;font-size:.75rem;
  color:#fff;text-shadow:0 1px 1px rgb(0 0 0/.35);
  background:rgb(var(--gem));box-shadow:0 0 10px rgb(var(--gem)/.45)}
.nexus-rarity__gem--common  {--gem:var(--nx-common)}
.nexus-rarity__gem--uncommon{--gem:var(--nx-uncommon)}
.nexus-rarity__gem--rare    {--gem:var(--nx-rare)}
.nexus-rarity__gem--mythic  {--gem:var(--nx-mythic)}
.nexus-rarity__gem--special {--gem:var(--nx-special)}
.nexus-rarity__gem--bonus   {--gem:var(--nx-bonus)}
.nexus-rarity__text{display:flex;flex-direction:column;min-inline-size:0;flex:1}
.nexus-rarity__name{font-family:Outfit,ui-sans-serif,system-ui,sans-serif;font-weight:700;
  font-size:.9375rem;line-height:1.2;color:rgb(var(--nx-text))}
.nexus-rarity__set{font-family:'Fira Code',ui-monospace,monospace;font-size:.6875rem;
  color:rgb(var(--nx-muted))}
.nexus-rarity__legend{flex-basis:100%;margin-block-start:.25rem;padding:.875rem 1rem;
  border:1px solid rgb(var(--nx-surface-hover));border-radius:.75rem;
  background:rgb(var(--nx-base));font-size:.75rem;line-height:1.55;color:rgb(var(--nx-muted))}
.nexus-rarity__legend.hidden{display:none}
.nexus-rarity__lede{margin:0 0 .75rem;color:rgb(var(--nx-text))}
.nexus-rarity__lede b,.nexus-rarity__list dt{color:rgb(var(--nx-text));font-weight:700}
.nexus-rarity__list{margin:0;display:grid;gap:.5rem}
.nexus-rarity__list>div{display:grid;grid-template-columns:7.5rem 1fr;gap:.5rem;align-items:baseline}
.nexus-rarity__list dt{display:flex;align-items:center;gap:.4rem;margin:0}
.nexus-rarity__list dd{margin:0}
.nexus-rarity__dot{inline-size:.625rem;block-size:.625rem;border-radius:999px;flex:none;
  background:rgb(var(--gem))}
.nexus-rarity__dot--common  {--gem:var(--nx-common)}
.nexus-rarity__dot--uncommon{--gem:var(--nx-uncommon)}
.nexus-rarity__dot--rare    {--gem:var(--nx-rare)}
.nexus-rarity__dot--mythic  {--gem:var(--nx-mythic)}
.nexus-rarity__dot--special {--gem:var(--nx-special)}
.nexus-rarity__dot--bonus   {--gem:var(--nx-bonus)}
.nexus-rarity__src{margin:.75rem 0 0;font-size:.6875rem;color:rgb(var(--nx-muted));opacity:.85}
@media (max-width:480px){.nexus-rarity__list>div{grid-template-columns:1fr}}
/* Tile borders for the two rarities CARD_RARITY_BORDER_MAP never had. Same
   40% / 5% treatment as the uncommon/rare/mythic utilities they sit beside. */
.nexus-tile--special{border-color:rgb(var(--nx-special)/.4);background-color:rgb(var(--nx-special)/.05)}
.nexus-tile--bonus  {border-color:rgb(var(--nx-bonus)/.4);background-color:rgb(var(--nx-bonus)/.05)}

/* ==========================================================================
   RULINGS — provenance (2026-09-03, Chad: "I was interested in the author of
   the rule"). Every ruling names who wrote it; the footer says when Nexus last
   refreshed its copy and links to Gatherer, Wizards' own database, where the
   originals are published. Data comes from get_card_rulings (card_rulings).
   ========================================================================== */
.nexus-ruling{border-block-end:1px solid rgb(var(--nx-surface-hover));padding-block-end:.75rem}
.nexus-ruling:last-of-type{border-block-end:0;padding-block-end:0}
.nexus-ruling__meta{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;
  font-family:'Fira Code',ui-monospace,monospace;font-size:.625rem;letter-spacing:.05em;
  color:rgb(var(--nx-muted))}
.nexus-ruling__by{font-weight:700;color:rgb(var(--nx-violet-lit))}
.nexus-ruling__by--scryfall{color:rgb(var(--nx-muted))}
.nexus-ruling__text{margin:.25rem 0 0;font-size:.875rem;line-height:1.6;color:rgb(var(--nx-text))}
.nexus-rulings-foot{margin-block-start:.25rem;padding-block-start:.75rem;
  border-block-start:1px solid rgb(var(--nx-surface-hover));font-size:.6875rem;line-height:1.5;
  color:rgb(var(--nx-muted));display:flex;flex-wrap:wrap;gap:.25rem .75rem;align-items:center}
.nexus-rulings-foot a{color:rgb(var(--nx-accent));font-weight:700;text-decoration:none}
.nexus-rulings-foot a:hover{text-decoration:underline}
.nexus-rulings-empty{font-size:.875rem;font-style:italic;line-height:1.6;color:rgb(var(--nx-muted));margin:0}
.nexus-rulings-fail{font-size:.8125rem;line-height:1.55;color:rgb(var(--nx-text));margin:0;
  padding:.625rem .75rem;border-radius:.5rem;
  border:1px solid rgb(var(--nx-warning)/.4);background:rgb(var(--nx-warning)/.08)}
.nexus-rulings-fail b{color:rgb(var(--nx-rare))}

/* ==========================================================================
   THEME CONTROLS (2026-09-03). The header button shows one of three glyphs
   for the three states; the stamp on <html> decides which. Account →
   Appearance holds the segmented control and the accent swatches; the
   selected option carries aria-pressed, which is what lights it.
   ========================================================================== */
.nexus-theme-btn .fa-sun,.nexus-theme-btn .fa-moon,.nexus-theme-btn .fa-circle-half-stroke{display:none}
:root:not([data-theme]) .nexus-theme-btn .fa-circle-half-stroke{display:inline-block}
:root[data-theme="light"] .nexus-theme-btn .fa-sun{display:inline-block}
:root[data-theme="dark"] .nexus-theme-btn .fa-moon{display:inline-block}
.nexus-seg{display:inline-flex;flex-wrap:wrap;gap:.25rem;padding:.25rem;border-radius:.625rem;
  border:1px solid rgb(var(--nx-surface-hover));background:rgb(var(--nx-base))}
.nexus-seg .nexus-btn[aria-pressed="true"],
.nexus-swatches .nexus-btn[aria-pressed="true"]{
  background:rgb(var(--nx-accent)/.14);color:rgb(var(--nx-accent));
  border-color:rgb(var(--nx-accent)/.55)}
.nexus-swatches{display:flex;flex-wrap:wrap;gap:.5rem}
.nexus-swatch__dot{display:block;inline-size:1.125rem;block-size:1.125rem;border-radius:999px;
  background:rgb(var(--sw));box-shadow:0 0 0 2px rgb(var(--nx-surface)),0 0 10px rgb(var(--sw)/.5)}
.nexus-swatch__dot--cyan  {--sw:0 225 255}
.nexus-swatch__dot--violet{--sw:167 139 250}
.nexus-swatch__dot--blue  {--sw:96 165 250}
.nexus-swatch__dot--green {--sw:74 222 128}
.nexus-swatch__dot--ruby  {--sw:240 82 75}
.nexus-swatch__dot--gold  {--sw:251 191 36}
@media (prefers-color-scheme:light){
  :root:not([data-theme="dark"]) .nexus-swatch__dot--cyan  {--sw:0 135 166}
  :root:not([data-theme="dark"]) .nexus-swatch__dot--violet{--sw:109 40 217}
  :root:not([data-theme="dark"]) .nexus-swatch__dot--blue  {--sw:29 78 216}
  :root:not([data-theme="dark"]) .nexus-swatch__dot--green {--sw:18 128 90}
  :root:not([data-theme="dark"]) .nexus-swatch__dot--ruby  {--sw:198 45 38}
  :root:not([data-theme="dark"]) .nexus-swatch__dot--gold  {--sw:161 98 7}
}
:root[data-theme="light"] .nexus-swatch__dot--cyan  {--sw:0 135 166}
:root[data-theme="light"] .nexus-swatch__dot--violet{--sw:109 40 217}
:root[data-theme="light"] .nexus-swatch__dot--blue  {--sw:29 78 216}
:root[data-theme="light"] .nexus-swatch__dot--green {--sw:18 128 90}
:root[data-theme="light"] .nexus-swatch__dot--ruby  {--sw:198 45 38}
:root[data-theme="light"] .nexus-swatch__dot--gold  {--sw:161 98 7}

/* ==========================================================================
   TUTORIALS (2026-09-03, Chad approved). Three pieces:
     .nexus-help-fab   the floating ? on every app page — replays the page's
                       tour whatever the user's dismissal choices were.
     .nexus-coach      one overlay: a ring around the spotlit control whose
                       box-shadow is the dimmer (so the control itself stays
                       bright AND clickable — the overlay passes pointer events
                       through; only the card catches them), and the card.
     .nexus-tut        the per-page list on Account → Tutorials.
   z: the coach sits above every modal (the highest is z-[130]); the FAB at
   135 so it stays reachable while the card window is open (that window has
   its own tour). Toasts are z-50 and only ever appear once a tour has closed.
   ========================================================================== */
.nexus-help-fab{position:fixed;z-index:135;inset-inline-start:1rem;
  inset-block-end:calc(1rem + env(safe-area-inset-bottom));
  --btn-min:2.75rem;font-size:1.125rem;box-shadow:0 8px 24px rgb(0 0 0/.35)}
.nexus-help-fab.hidden{display:none}
@media (max-width:1023px){
  .nexus-help-fab{inset-block-end:calc(var(--nexus-rail-bar-h,0px) + 1rem + env(safe-area-inset-bottom))}
}
.nexus-coach{position:fixed;inset:0;z-index:140;pointer-events:none}
.nexus-coach.hidden{display:none}
.nexus-coach__ring{position:absolute;border-radius:.75rem;pointer-events:none;
  box-shadow:0 0 0 9999px rgb(var(--nx-dark)/.72),0 0 0 3px rgb(var(--nx-accent)),
             0 0 24px rgb(var(--nx-accent)/.6);
  transition:top .25s ease,left .25s ease,width .25s ease,height .25s ease}
.nexus-coach__ring--none{box-shadow:0 0 0 9999px rgb(var(--nx-dark)/.72)}
.nexus-coach__card{position:absolute;pointer-events:auto;
  inline-size:min(23rem,calc(100vw - 2rem));padding:1rem 1.125rem;border-radius:.875rem;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-surface-hover));
  box-shadow:0 20px 50px rgb(0 0 0/.5);color:rgb(var(--nx-text));outline:none}
.nexus-coach__step{font-family:'Fira Code',ui-monospace,monospace;font-size:.625rem;
  letter-spacing:.08em;text-transform:uppercase;color:rgb(var(--nx-accent));margin:0 0 .375rem}
.nexus-coach__title{font-family:Outfit,ui-sans-serif,system-ui,sans-serif;font-weight:800;
  font-size:1rem;line-height:1.25;margin:0 0 .375rem;color:rgb(var(--nx-text))}
.nexus-coach__body{font-size:.8125rem;line-height:1.55;color:rgb(var(--nx-muted));margin:0}
.nexus-coach__body b{color:rgb(var(--nx-text))}
.nexus-coach__dots{display:flex;gap:.3rem;margin-block-start:.75rem}
.nexus-coach__dots i{inline-size:.375rem;block-size:.375rem;border-radius:999px;background:rgb(var(--nx-track))}
.nexus-coach__dots i.on{background:rgb(var(--nx-accent))}
.nexus-coach__acts{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;margin-block-start:.875rem}
.nexus-coach__spacer{flex:1}
@media (prefers-reduced-motion:reduce){.nexus-coach__ring{transition:none}}
.nexus-tut{display:grid;gap:.5rem}
.nexus-tut__row{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem .875rem;
  padding:.75rem .875rem;border:1px solid rgb(var(--nx-surface-hover));border-radius:.625rem;
  background:rgb(var(--nx-base))}
.nexus-tut__name{font-weight:700;color:rgb(var(--nx-text));font-size:.84375rem}
.nexus-tut__sub{flex-basis:100%;font-size:.75rem;color:rgb(var(--nx-muted));line-height:1.5}
.nexus-tut__acts{margin-inline-start:auto;display:flex;gap:.375rem}

/* ==========================================================================
   SHARED EDITING PHASE 4 — the nudge, and the roster it depends on
   Chad ruled the layout 2026-09-05: "fly out on the card like you discussed",
   so a nudge is SENT from the flyout every card already has and ARRIVES on the
   card it names. New classes, so their rules live here (THE RULES #1), and
   every state is a fixed class name, never composed from data (#2).
   ========================================================================== */

/* The nudge options inside each card's action menu. Hidden until somebody else
   is actually in the deck — markDeckCompany() sets the attribute on <body>, so
   one toggle covers every card without redrawing the manifest. Declared here,
   BELOW line ~417, which means it beats .hidden by source order; that is why
   the block is switched with this rule and not by adding/removing .hidden
   (TRAPS.md 2026-09-03). */
.nexus-ping-opts{display:none}
body[data-nexus-company="yes"] .nexus-ping-opts{display:block}

/* The arriving nudge. Fixed, because it is positioned from the card's
   viewport rect; translated so it sits centred just above the card it names.
   z-index 141: one above the toast layer, because a nudge points at a specific
   thing on screen and must not end up under a toast that happens to be up. */
.nexus-ping-fly{
  position:fixed;z-index:141;transform:translate(-50%,-115%);
  pointer-events:auto;animation:nexus-ping-in .18s ease-out;
}
.nexus-ping-fly__btn{
  display:flex;flex-direction:column;align-items:flex-start;gap:.125rem;
  padding:.5rem .75rem;border-radius:.625rem;cursor:pointer;
  background:rgb(var(--nx-surface));border:1px solid rgb(var(--nx-accent));
  box-shadow:0 10px 30px rgb(0 0 0/.55);
  font-family:Outfit,ui-sans-serif,system-ui,sans-serif;text-align:left;
}
.nexus-ping-fly__who{
  font-family:'Fira Code',ui-monospace,monospace;font-size:.625rem;
  letter-spacing:.06em;text-transform:uppercase;color:rgb(var(--nx-accent));
}
.nexus-ping-fly__what{font-size:.8125rem;font-weight:700;color:rgb(var(--nx-text));white-space:nowrap}
/* A little tail, so it reads as pointing AT the card rather than floating over it. */
.nexus-ping-fly__btn::after{
  content:'';position:absolute;inset-block-start:100%;inset-inline-start:50%;
  translate:-50% 0;border:6px solid transparent;border-block-start-color:rgb(var(--nx-accent));
}
.nexus-ping-fly__btn{position:relative}
/* The card being nudged about, so the eye lands on it and not just the label. */
.nexus-ping-target{outline:2px solid rgb(var(--nx-accent));outline-offset:2px;border-radius:.75rem}
@keyframes nexus-ping-in{from{opacity:0;transform:translate(-50%,-95%)}to{opacity:1;transform:translate(-50%,-115%)}}
@media (prefers-reduced-motion:reduce){.nexus-ping-fly{animation:none}}

/* ===========================================================================
   Upcoming cards, card rows, and the block reorder panel — 2026-09-06
   ---------------------------------------------------------------------------
   Three related things from one request: browse what is not out yet in the
   Products pane, drop those cards into an article as a row, and reorder the
   blocks of that article without leaving the textarea behind.
   =========================================================================== */

/* --- The card row inside a published article ------------------------------
   nexus_post_render tags a paragraph that contains NOTHING BUT two or more
   card tokens with this class. Without it the references are inline elements
   and wrap like words -- ragged, different sizes, no rhythm. Here they become
   equal columns that wrap as a unit. The selector is deliberately scoped to
   .nexus-cardrow only: an inline mention inside a sentence must keep flowing
   with the text, and that is the whole distinction the syntax encodes. */
.nexus-cardrow{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));
  gap:.75rem;margin-block:1.25rem;
}
.nexus-cardrow .nexus-cardref{
  display:flex;flex-direction:column;gap:.4rem;align-items:stretch;
  padding:.5rem;border-radius:.5rem;background:rgb(var(--nx-card));
  border:1px solid rgb(var(--nx-surface-hover));text-decoration:none;
}
.nexus-cardrow .nexus-cardref:hover{border-color:rgb(var(--nx-accent))}
/* The base .nexus-cardref__art is a HOVER POPOVER: absolutely positioned above
   the link, opacity 0, visibility hidden, pointer-events none. That is right
   for a card named inside a sentence. In a row the art IS the content, so all
   five of those have to be undone -- sizing it alone left a loaded 141px image
   inside a 50px box, invisible. Measured, not guessed. */
.nexus-cardrow .nexus-cardref__art{
  position:static;inset:auto;order:-1;
  opacity:1;visibility:visible;pointer-events:auto;
  inline-size:100%;max-inline-size:none;aspect-ratio:16/10;
  object-fit:cover;object-position:center 25%;
  border:0;box-shadow:none;border-radius:.35rem;display:block;
}
.nexus-cardrow .nexus-cardref__name{
  font-size:.78rem;font-weight:700;line-height:1.3;text-align:center;
}

/* --- The browser: set chips + card grid ---------------------------------- */
.nexus-up__chips{display:flex;flex-wrap:wrap;gap:.4rem;margin-block:.5rem .85rem}
.nexus-up__n{
  display:inline-block;margin-inline-start:.35rem;padding:0 .35rem;
  border-radius:.6rem;background:rgb(var(--nx-track));font-size:.7rem;font-weight:800;
}
.nexus-up__when{margin-inline-start:.3rem;font-size:.68rem;opacity:.75}

.nexus-up__grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(8.5rem,1fr));
  gap:.6rem;max-block-size:34rem;overflow-y:auto;padding-inline-end:.25rem;
}
/* A tile is a real <button>: it takes focus, and Enter and Space both fire it
   for free. It holds no other focusable control -- the tick lives in
   aria-pressed and a border, because a button may never contain a button. */
.nexus-up__card{
  display:flex;flex-direction:column;gap:.3rem;padding:.4rem;text-align:start;
  border:1px solid rgb(var(--nx-surface-hover));border-radius:.5rem;
  background:rgb(var(--nx-card));cursor:pointer;font:inherit;color:inherit;
}
.nexus-up__card:hover{border-color:rgb(var(--nx-accent))}
.nexus-up__card:focus-visible{outline:2px solid rgb(var(--nx-accent));outline-offset:2px}
.nexus-up__card--on{
  border-color:rgb(var(--nx-accent));
  box-shadow:inset 0 0 0 1px rgb(var(--nx-accent));
}
.nexus-up__card img{
  inline-size:100%;aspect-ratio:16/10;object-fit:cover;object-position:center 25%;
  border-radius:.35rem;display:block;
}
.nexus-up__name{font-size:.74rem;font-weight:700;line-height:1.25}
.nexus-up__meta{
  font-size:.66rem;color:rgb(var(--nx-muted));line-height:1.2;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.nexus-up__foot{
  display:flex;gap:.35rem;align-items:center;justify-content:space-between;
  font-size:.66rem;color:rgb(var(--nx-muted));
}
.nexus-up__done{
  padding:0 .3rem;border-radius:.5rem;background:rgb(var(--nx-track));
  font-weight:700;font-size:.62rem;
}

/* --- The composer's collapsible strip ------------------------------------ */
.nexus-up__wrap{
  border:1px solid rgb(var(--nx-surface-hover));border-radius:.6rem;
  padding:.6rem .75rem;margin-block-end:.9rem;background:rgb(var(--nx-surface));
}
.nexus-up__summary{
  cursor:pointer;font-size:.82rem;font-weight:700;display:flex;gap:.45rem;
  align-items:center;flex-wrap:wrap;
}
.nexus-up__summary::-webkit-details-marker{display:none}
.nexus-up__bar{
  display:flex;gap:.45rem;align-items:center;flex-wrap:wrap;margin-block-end:.6rem;
}
.nexus-up__count{font-size:.74rem;color:rgb(var(--nx-muted));flex:1 1 12rem}
.nexus-up__grid--pick{max-block-size:22rem}

/* --- The reorder panel ----------------------------------------------------
   Deliberately plain. It is a map of the article, not a second editor: the
   textarea above stays the writing surface, and these strips are rebuilt from
   it every time the panel opens. */
.nexus-reorder{
  border:1px solid rgb(var(--nx-surface-hover));border-radius:.6rem;
  padding:.6rem .75rem;margin-block-end:.9rem;background:rgb(var(--nx-surface));
}
.nexus-reorder__lede{font-size:.74rem;color:rgb(var(--nx-muted));margin-block-end:.5rem}
.nexus-reorder__row{
  display:flex;gap:.5rem;align-items:center;padding:.35rem .4rem;
  border:1px solid transparent;border-radius:.4rem;font-size:.78rem;cursor:grab;
}
.nexus-reorder__row + .nexus-reorder__row{margin-block-start:.2rem}
.nexus-reorder__row:hover{background:rgb(var(--nx-surface-hover))}
.nexus-reorder__row--dragging{opacity:.45;cursor:grabbing}
.nexus-reorder__row--over{border-color:rgb(var(--nx-accent))}
.nexus-reorder__kind{
  flex:0 0 auto;font-weight:800;font-size:.68rem;text-transform:uppercase;
  letter-spacing:.04em;color:rgb(var(--nx-muted));min-inline-size:5.5rem;
}
.nexus-reorder__detail{
  flex:1 1 auto;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;
}

@media (max-width:640px){
  .nexus-up__grid{grid-template-columns:repeat(auto-fill,minmax(7rem,1fr))}
  .nexus-reorder__kind{min-inline-size:0}
}
