/* ds-app.css — THE APP SHELL, IN THE DESIGN SYSTEM'S LANGUAGE
 *
 * Load order matters: fonts.css → style.css → game.css → ds.css → ds-app.css.
 * ds.css brings the tokens and primitives; this file re-dresses the COMPONENTS
 * that game.css already defines and that profile / market / game all share
 * (.panel, .tab, .cardc, .card-grid, .filterbar, .btn, .userbar).
 *
 * WHY A SHARED FILE AND NOT PER-PAGE CSS: those components are the reason the
 * three biggest screens drifted apart in the first place. Every page that
 * restyled .panel in its own <style> block made the next page's .panel a little
 * more different. There is now exactly one place to change them.
 *
 * WHAT THIS DELIBERATELY DOES NOT TOUCH: layout, IDs, or anything the page JS
 * queries. profile.js drives the deck builder, the virtualised collection grid,
 * bulk-list and drag-and-drop off these class names — this is paint, not surgery.
 */

/* ── the recurring bug: a component with display:flex beats [hidden].
      This has now been found four separate times. Guard it once, here. ── */
[hidden] { display: none !important; }

/* ── READABILITY FLOOR ──
   The audit found 24 rules under 12px on profile alone, down to 9px. Nothing in
   an interface should be smaller than 12px; the design system's smallest step is
   --t-micro (10px) and that is reserved for wide-tracked LABELS, never prose. */
.muted, .cmeta, .cardc .cn, .deck-row, .pf-rank, .filterbar input, .filterbar select { font-size: 12.5px; }

/* ── PANEL: angular, not a rounded rectangle (ds rule 4) ── */
.panel {
  background: var(--panel-solid);
  border: 1px solid var(--line);
  border-radius: 0;
  box-shadow: 0 18px 48px rgba(0,0,0,.5);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)),
    calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}
/* the engraved rim-light game.css draws on ::before assumed rounded corners and
   pokes out of the clip on the cut edges — the clip already reads as a bevel */
.panel::before { display: none; }

/* ── SECTION HEADINGS: hierarchy by size, not by another box ── */
.row-between > b {
  font-family: Cinzel, serif; font-weight: 900; font-size: var(--t-title);
  letter-spacing: .06em; color: var(--gold); text-shadow: none;
}

/* ── TABS: text with a gold tick, not gold pills.
      Master Duel's navigation is type — size and a mark carry the state. ── */
.tabs { gap: var(--s3); border-bottom: 1px solid var(--line); padding-bottom: 0; }
.tab {
  padding: 10px 2px var(--s1); border: none; border-radius: 0; background: none;
  box-shadow: none; overflow: visible; color: var(--muted);
  font-family: var(--font-ui); font-size: var(--t-cap); font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; transition: color .18s var(--ease);
}
.tab::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--gold); transform: scaleX(0); transform-origin: left;
  transition: transform .22s var(--ease);
}
.tab:hover { color: var(--ink); transform: none; border-color: transparent; box-shadow: none; }
.tab.active {
  color: var(--gold); background: none; font-weight: 900; transform: none;
}
.tab.active::after { transform: scaleX(1); box-shadow: 0 0 12px rgba(231,198,107,.55); }

/* ── CARDS IN A GRID: cut corner, quieter frame, art does the talking ── */
.cardc {
  border-radius: 0; border: 1px solid var(--line); border-left-width: 3px;
  background: rgba(18,15,22,.8);
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
}
.cardc:hover { transform: translateY(-3px); box-shadow: 0 14px 30px rgba(0,0,0,.6); }
.cardc.click:hover { border-color: var(--line-hi); }
.card-grid { gap: var(--s2); }

/* ── FORM CONTROLS ── */
.filterbar input, .filterbar select, .filterbar .f-reset {
  border-radius: 0; border: 1px solid var(--line); background: rgba(0,0,0,.32);
  color: var(--ink);
}
.filterbar input:focus, .filterbar select:focus { outline: none; border-color: var(--line-hi); }

/* ── BUTTONS: one filled primary per screen, everything else outlined ── */
.btn, button.btn, .btn-pill {
  border-radius: 0; box-shadow: none;
  clip-path: polygon(10px 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 10px);
  font-family: var(--font-ui); font-weight: 700; letter-spacing: .1em;
}
.btn-primary {
  background: linear-gradient(180deg, var(--gold-hi), var(--gold) 48%, var(--gold-lo));
  color: #17110a; border: none;
}
.btn-primary:hover { filter: brightness(1.06); }

/* ── USERBAR: angular, matching the menu's identity block ── */
.userbar {
  border-radius: 0; border: 1px solid var(--line); background: var(--panel);
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
}
.userbar .pfp { border-radius: 0; border: 1px solid var(--line); }

/* ── small-card art: crop to the artwork window rather than squashing a whole card ── */
.cardc img.art, .cardc .cart img { object-fit: cover; object-position: 50% 30%; }

@media (prefers-reduced-motion: reduce) {
  .tab::after, .cardc { transition: none; }
}

/* ── PRODUCT SHELF ──
   The two Series II SKUs each carried a full colour identity: a blue (court) or
   red (storm) panel tint, matching border, matching stage glow, and a coloured
   title. That is a second and third accent competing with the gold on the page
   where players spend money — and it is redundant, because the WRAPPER ART is
   already sitting right there doing exactly that job.
   The tint goes; the art keeps the identity. A single hairline in the SKU's hue
   is all the colour-coding that survives, which is enough to tell them apart
   without either one shouting. */
.s2-sku, .s2-sku.court, .s2-sku.storm {
  background: var(--panel-solid);
  border-color: var(--line);
  border-radius: 0;
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)),
    calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}
.s2-sku.court { border-top: 2px solid rgba(123,161,232,.55); }
.s2-sku.storm { border-top: 2px solid rgba(232,130,110,.55); }
.s2-sku.court:hover, .s2-sku.storm:hover {
  border-color: var(--line-hi); box-shadow: 0 16px 36px rgba(0,0,0,.55);
}
.s2-sku.court:hover { border-top-color: rgba(123,161,232,.9); }
.s2-sku.storm:hover { border-top-color: rgba(232,130,110,.9); }

/* the stage behind the wrapper: neutral, so the pack art is the only colour */
.s2-sku .s2-stage, .s2-sku.court .s2-stage, .s2-sku.storm .s2-stage {
  background: radial-gradient(70% 86% at 50% 100%, rgba(231,198,107,.10), transparent 72%);
}
/* product names are product names — gold, like every other heading on the site */
.s2-sku .s2-name, .s2-sku.court .s2-name, .s2-sku.storm .s2-name {
  color: var(--gold); text-shadow: none;
}

/* the discount flag was an orange-red pill — a fourth colour on the page, and the
   loudest one, on the smallest element. Gold on dark says "sale" just as clearly. */
.s2-off { background: var(--gold); color: #17110a; border-radius: 0; padding: 2px 8px;
  letter-spacing: .06em; }

/* ── PAY BUTTONS: the burn leads ──
   The filled gold button was "Pay with SOL" and the burn was a thin orange outline,
   so the loudest control on the shelf was the one that costs the player MORE ($10 vs
   $5 during a sale) and does nothing for the token. One filled primary per screen,
   and it should be the action you actually want taken — so the $YUGIOH burn takes the
   gold and SOL becomes the outlined alternative. Both remain equally available; only
   the emphasis moves. No handler, price or quote is touched — data-s2burn and
   data-s2sol are exactly where they were. */
.cbuy.tok {
  background: linear-gradient(180deg, var(--gold-hi), var(--gold) 48%, var(--gold-lo));
  color: #17110a; border: none; font-weight: 800;
}
.cbuy.tok:hover { color: #17110a; filter: brightness(1.06);
  box-shadow: 0 10px 28px rgba(231,198,107,.42); }
.cbuy.tok .cbuy-price, .cbuy.tok s { color: #17110a; }
.cbuy.tok s { opacity: .5; }

.cbuy.sol {
  background: transparent; color: var(--gold); border: 1px solid var(--line-hi);
  font-weight: 700;
}
.cbuy.sol:hover { background: rgba(231,198,107,.1); color: var(--gold-hi);
  box-shadow: none; }
.cbuy.sol .cbuy-price { color: var(--gold); }

/* The inline discount flag needs dark ink inside the GOLD button — but this was written as
   `.cbuy .off`, unscoped, so it hit `.cbuy.sol` too. That variant is transparent on a dark
   panel, so the same dark ink landed on near-black and the discount flag rendered invisible
   on the SOL button. Its own comment said "inside a now-gold button"; the selector never said
   so. Scoped per variant: dark ink on gold, gold ink on the outlined one. */
.cbuy.tok .off { background: rgba(23,17,10,.22); color: #17110a; border-radius: 0; }
.cbuy.sol .off { background: rgba(231,198,107,.14); color: var(--gold); border-radius: 0; }

/* ══ CONTENT PAGES ════════════════════════════════════════════════════════
   The remaining pages share almost no class vocabulary — tournament is all
   .ch-*, leaderboard .lb-*, the Book .bk-*, profiles .dc-* — so there is
   nothing common to re-dress by name. What they DO share is the rounded
   rectangle: 26 radii on profile alone, and every page picked its own value
   (7px, 9px, 10px, 11px, 12px, 14px, 16px, 22px). That inconsistency is a
   large part of why moving between pages felt like moving between products.

   border-radius is a purely visual property — zeroing it cannot shift a
   layout, break a handler or change a measurement — which makes it the one
   thing safe to set site-wide without auditing 3,788 lines of page CSS. */
/* !important is deliberate and is the right tool exactly here: these rules live in a
   LINKED sheet, but every page sets its radii from its own <style> block using class
   selectors, which outrank an element selector on both specificity and order. Without
   it the blanket silently loses — measured after the first attempt: 20px, 18px, 12px,
   10px, 7px and 999px all still rendering. A house rule any page can quietly opt out
   of is not a house rule. */
body :is(div, section, article, aside, header, footer, nav, main,
         a, button, input, select, textarea, label, summary, details,
         table, thead, tbody, tr, td, th, ul, ol, li, span, img, figure) {
  border-radius: 0 !important;
}

/* …with the exceptions that are round because round MEANS something: a live
   dot is a dot, and a progress ring is a ring. Re-asserted after the blanket. */
.yg-live, [class*="dot"], .lp-dot, .co-dot, .online-dot,
.spinner, [class*="ring"] { border-radius: 50% !important; }

/* headings across the content pages: one treatment, from the type scale */
body :is(h1, h2, h3) { font-family: Cinzel, serif; letter-spacing: .05em; }

/* ── ONE GROUND ──
   Every page had grown its own backdrop, and they drifted apart in TEMPERATURE, not
   just in pattern: the menu sits on a cool near-black while tournament, leaderboard
   and the rest sit on a warm amber-brown. Moving between them changed the colour of
   the light, which reads as leaving one product and entering another. That is the
   single biggest reason the site felt like several sites.

   One ground everywhere, cool. Pages that genuinely need their own art layer it back
   on top; the duel board and the broadcast pages do not load this file at all and
   keep exactly what they have. */
body {
  background:
    radial-gradient(1200px 820px at 62% -12%, rgba(231,198,107,.06), transparent 62%),
    linear-gradient(165deg, var(--bg1) 0%, #0a0810 48%, var(--bg0) 100%) fixed !important;
  color: var(--ink);
}

/* rarity chips lose their padding now that they are words rather than pills
   (the fill itself is set inline by user.js, so it had to change at the source) */
.rtag { padding: 0; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; }
