/*!
 * design-system.css - the utilities the storefront's markup needs and the
 * prebuilt Tailwind subset in tailwindcss.css does not ship.
 *
 * WHY THIS FILE EXISTS
 * The design this storefront is ported from is a Tailwind + shadcn build whose
 * config defines a *bare* `primary` colour (`bg-primary`, `bg-primary/10`,
 * `text-primary-foreground`, `ring-primary/20`) and a full `slate` palette, and
 * whose JIT emits arbitrary values (`w-[10.5rem]`, `min-h-[80vh]`,
 * `leading-[17px]`, `grid-cols-[minmax(0,1fr)_auto]`).
 *
 * This project has no Tailwind build at all: tailwindcss.css is a static,
 * pre-generated v3.3.3 dump loaded as a plain <link>. It carries a *numbered*
 * primary scale (`bg-primary-500` and its alpha ladder) but no bare `primary`,
 * no `slate`, no `line-clamp`, no `aspect-square`, and no arbitrary values -
 * so markup copied from the design rendered completely unstyled.
 *
 * Rather than introduce a Tailwind pipeline (whose preflight would reset
 * Vuetify and Bootstrap and change every existing page), this sheet is loaded
 * LAST and is strictly additive: it defines only classes that are absent from
 * the dump. Nothing here overrides an existing utility, so no page that
 * renders correctly today can change.
 *
 * `--ds-primary` is an "R G B" triplet so the `/10`, `/20`, `/90` alpha
 * variants work; layouts/default.vue writes it from the admin's theme colour
 * alongside the other theme custom properties.
 */

:root {
  --ds-primary: 33 98 135;
  --ds-primary-foreground: 255 255 255;
  --ds-muted-foreground: 100 116 139;
  --ds-ring-offset: 255 255 255;
  /* shadcn's `bg-background`. The content-box colour is admin-settable, but a
     slide-out panel over a dimmed page has to stay opaque white, so this is not
     wired to --content-box-color. */
  --ds-background: 255 255 255;
}

/* The design's page shell. `container` here only gains auto margins: the
   horizontal padding still comes from home.css, and adding padding would beat
   the `px-0` some existing grids rely on. */
.container {
  margin-left: auto;
  margin-right: auto;
}

.antialiased {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ---------------------------------------------------------------------------
   Vuetify reset corrections.

   `!important` is unavoidable here. There is no webpack-extracted CSS in this
   build (dist/_nuxt carries no .css), so Vuetify's sheet and every component
   <style> block are injected at runtime by style-loader - i.e. AFTER this file
   in <head>. A plain rule of equal specificity would always lose.

   1. vuetify.min.css sets `html{overflow-y:scroll}`, which pins a scrollbar
      gutter to the right edge of every page whether or not the page actually
      scrolls. That permanent bar is not part of the design.
   2. `.v-application--wrap{backface-visibility:hidden}` is a compositing hint
      Vuetify 2 uses to stop iOS repaint flicker. Its side effect is that the
      wrap becomes a containing block and a stacking context, which traps
      `position:fixed` overlays (the account sheet) inside it and lets the
      sticky header paint over them.
   --------------------------------------------------------------------------- */
html {
  overflow-y: auto !important;
}

.v-application--wrap {
  -webkit-backface-visibility: visible !important;
  backface-visibility: visible !important;
}

/* ---------------------------------------------------------------------------
   Slate palette. Tailwind's own values, so a class name lifted from the design
   resolves to the colour the designer saw.
   --------------------------------------------------------------------------- */
.bg-slate-50 { background-color: #f8fafc; }
.bg-slate-100 { background-color: #f1f5f9; }
.bg-slate-200 { background-color: #e2e8f0; }
.bg-slate-300 { background-color: #cbd5e1; }
.bg-slate-400 { background-color: #94a3b8; }
.bg-slate-900 { background-color: #0f172a; }
.hover\:bg-slate-400:hover { background-color: #94a3b8; }
.disabled\:bg-slate-100:disabled { background-color: #f1f5f9; }

.text-slate-400 { color: #94a3b8; }
.text-slate-500 { color: #64748b; }
.text-slate-600 { color: #475569; }
.text-slate-700 { color: #334155; }
.text-slate-800 { color: #1e293b; }
.text-slate-900 { color: #0f172a; }
.text-slate-950 { color: #020617; }
.text-neutral-500 { color: #737373; }
.text-emerald-600 { color: #059669; }
.text-muted-foreground { color: rgb(var(--ds-muted-foreground) / 1); }
.hover\:text-black:hover { color: #000; }
.disabled\:text-slate-400:disabled { color: #94a3b8; }
.group:hover .group-hover\:text-slate-950 { color: #020617; }

.border-slate-200 { border-color: #e2e8f0; }
.border-slate-300 { border-color: #cbd5e1; }
.disabled\:border-slate-200:disabled { border-color: #e2e8f0; }

.bg-white\/95 { background-color: hsla(0, 0%, 100%, 0.95); }
.bg-white\/90 { background-color: hsla(0, 0%, 100%, 0.9); }

/* ---------------------------------------------------------------------------
   The bare `primary` colour, driven by the admin's theme colour. The numbered
   `primary-400/500` scale in custom-styles.css is left exactly as it is - these
   are new names, not replacements.
   --------------------------------------------------------------------------- */
.bg-primary { background-color: rgb(var(--ds-primary) / 1); }
.bg-primary\/5 { background-color: rgb(var(--ds-primary) / 0.05); }
.bg-primary\/10 { background-color: rgb(var(--ds-primary) / 0.1); }
.bg-primary\/15 { background-color: rgb(var(--ds-primary) / 0.15); }
.bg-primary\/20 { background-color: rgb(var(--ds-primary) / 0.2); }
.bg-primary\/90 { background-color: rgb(var(--ds-primary) / 0.9); }
.hover\:bg-primary:hover { background-color: rgb(var(--ds-primary) / 1); }
.hover\:bg-primary\/90:hover { background-color: rgb(var(--ds-primary) / 0.9); }
.hover\:bg-primary\/20:hover { background-color: rgb(var(--ds-primary) / 0.2); }

.text-primary { color: rgb(var(--ds-primary) / 1); }
.text-primary-foreground { color: rgb(var(--ds-primary-foreground) / 1); }
.hover\:text-primary:hover { color: rgb(var(--ds-primary) / 1); }
.hover\:text-primary-foreground:hover { color: rgb(var(--ds-primary-foreground) / 1); }
.group:hover .group-hover\:text-primary { color: rgb(var(--ds-primary) / 1); }

.border-primary { border-color: rgb(var(--ds-primary) / 1); }
.border-primary\/15 { border-color: rgb(var(--ds-primary) / 0.15); }
.border-primary\/20 { border-color: rgb(var(--ds-primary) / 0.2); }
.border-primary\/30 { border-color: rgb(var(--ds-primary) / 0.3); }
.hover\:border-primary\/30:hover { border-color: rgb(var(--ds-primary) / 0.3); }

.ring-primary\/20 { --tw-ring-color: rgb(var(--ds-primary) / 0.2); }
.ring-primary\/30 { --tw-ring-color: rgb(var(--ds-primary) / 0.3); }
.focus-visible\:ring-primary\/30:focus-visible { --tw-ring-color: rgb(var(--ds-primary) / 0.3); }

/* shadcn writes its focus ring against a background token; without a Tailwind
   config there is nothing to resolve it, so it is spelled out here. */
.ring-offset-background { --tw-ring-offset-color: rgb(var(--ds-ring-offset) / 1); }

/* ---------------------------------------------------------------------------
   Sizing, spacing and position gaps.
   --------------------------------------------------------------------------- */
.h-auto { height: auto; }
.h-9 { height: 2.25rem; }
.h-14 { height: 3.5rem; }
.w-3\.5 { width: 0.875rem; }
.w-\[10\.5rem\] { width: 10.5rem; }
.min-h-16 { min-height: 4rem; }
.min-h-\[34px\] { min-height: 34px; }
.min-h-\[80vh\] { min-height: 80vh; }
.min-w-5 { min-width: 1.25rem; }
.min-w-9 { min-width: 2.25rem; }
.hover\:w-2\.5:hover { width: 0.625rem; }

.shrink-0 { flex-shrink: 0; }
.grow-0 { flex-grow: 0; }
.basis-full { flex-basis: 100%; }
.items-stretch { align-items: stretch; }
.mt-auto { margin-top: auto; }
.z-40 { z-index: 40; }

.mt-0\.5 { margin-top: 0.125rem; }
.ml-1\.5 { margin-left: 0.375rem; }
.mb-6 { margin-bottom: 1.5rem; }
.mb-12 { margin-bottom: 3rem; }
.pl-0 { padding-left: 0; }
.pl-3 { padding-left: 0.75rem; }
.pr-2 { padding-right: 0.5rem; }
.pr-2\.5 { padding-right: 0.625rem; }
.space-x-4 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-x-reverse: 0;
  margin-left: calc(1rem * (1 - var(--tw-space-x-reverse)));
  margin-right: calc(1rem * var(--tw-space-x-reverse));
}

.left-2 { left: 0.5rem; }
.right-2 { right: 0.5rem; }
.top-2 { top: 0.5rem; }
.-right-1 { right: -0.25rem; }
.-top-1 { top: -0.25rem; }
.inset-x-0 { left: 0; right: 0; }

/* ---------------------------------------------------------------------------
   Grid, aspect ratio and text clamping.
   --------------------------------------------------------------------------- */
.grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-cols-7 { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.grid-cols-\[minmax\(0\2c 1fr\)_auto\] { grid-template-columns: minmax(0, 1fr) auto; }
.gap-x-3 { column-gap: 0.75rem; }
.gap-y-6 { row-gap: 1.5rem; }
.gap-2\.5 { gap: 0.625rem; }

/*
  The home page's section rhythm and the shop grid's widest breakpoint. The
  source used `mt-6 md:mt-10` on every category section and
  `grid-cols-2 md:grid-cols-3 lg:grid-cols-4` on the physical-goods grids; the
  tailwind dump carries `md:mt-10` and `md:grid-cols-3` but not these three,
  because the pages they were generated from did not happen to use them.
*/
.mt-6 { margin-top: 1.5rem; }
@media (min-width: 1024px) {
  .lg\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.aspect-square { aspect-ratio: 1 / 1; }
.object-cover { object-fit: cover; }

.line-clamp-2 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.text-\[13px\] { font-size: 13px; }
.leading-\[17px\] { line-height: 17px; }
.line-through { text-decoration-line: line-through; }

/* ---------------------------------------------------------------------------
   Shadows, blur, transitions and the transforms the cards hover with.
   --------------------------------------------------------------------------- */
.shadow-none { --tw-shadow: 0 0 #0000; box-shadow: 0 0 #0000; }
.backdrop-blur { -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.transition-shadow {
  transition-property: box-shadow;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 0.15s;
}
.shadow-\[0_1px_8px_rgba\(15\2c 23\2c 42\2c 0\.04\)\] {
  box-shadow: 0 1px 8px rgba(15, 23, 42, 0.04);
}
.shadow-slate-900\/10 { --tw-shadow-color: rgba(15, 23, 42, 0.1); --tw-shadow: var(--tw-shadow-colored); }
.hover\:shadow-slate-900\/15:hover { --tw-shadow-color: rgba(15, 23, 42, 0.15); --tw-shadow: var(--tw-shadow-colored); }
.shadow-primary\/40 { --tw-shadow-color: rgb(var(--ds-primary) / 0.4); --tw-shadow: var(--tw-shadow-colored); }
.hover\:shadow-xl:hover {
  --tw-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
  --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);
}

.hover\:-translate-y-0\.5:hover {
  --tw-translate-y: -0.125rem;
  transform: translate(var(--tw-translate-x, 0), -0.125rem) rotate(var(--tw-rotate, 0)) skewX(var(--tw-skew-x, 0))
    skewY(var(--tw-skew-y, 0)) scaleX(var(--tw-scale-x, 1)) scaleY(var(--tw-scale-y, 1));
}
.group:hover .group-hover\:scale-\[1\.04\] {
  transform: translate(var(--tw-translate-x, 0), var(--tw-translate-y, 0)) scale(1.04);
}
.group:hover .group-hover\:scale-\[1\.03\] {
  transform: translate(var(--tw-translate-x, 0), var(--tw-translate-y, 0)) scale(1.03);
}
.group:hover .group-hover\:opacity-100 { opacity: 1; }

.bg-gradient-to-t {
  background-image: linear-gradient(to top, var(--tw-gradient-stops));
}
.from-black\/20 {
  --tw-gradient-from: rgba(0, 0, 0, 0.2);
  --tw-gradient-to: rgba(0, 0, 0, 0);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.to-transparent { --tw-gradient-to: transparent; }

.disabled\:pointer-events-none:disabled { pointer-events: none; }

/* ---------------------------------------------------------------------------
   The banner carousel's one hook.

   There is deliberately no height here. The source's `.carousel__item img` was
   `width:100%; height:auto`, so a banner renders at its own ratio; the fixed
   150/220/300/360px boxes that used to live here letterboxed the catalogue's
   16:9 banners inside a short white strip.
   --------------------------------------------------------------------------- */
.banner-item {
  display: block;
}

/* ---------------------------------------------------------------------------
   Responsive variants. The dump generated `sm:`/`md:` forms only for the
   utilities the source pages happened to use, so the ones the new markup needs
   are declared here.
   --------------------------------------------------------------------------- */
@media (min-width: 640px) {
  .sm\:my-6 { margin-top: 1.5rem; margin-bottom: 1.5rem; }
  .sm\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (min-width: 768px) {
  .md\:min-h-20 { min-height: 5rem; }
  .md\:min-h-0 { min-height: 0; }
  .md\:w-\[13rem\] { width: 13rem; }
  .md\:w-7 { width: 1.75rem; }
  .md\:h-7 { height: 1.75rem; }
  .md\:grid-cols-7 { grid-template-columns: repeat(7, minmax(0, 1fr)); }
  .md\:gap-2 { gap: 0.5rem; }
  .md\:gap-3 { gap: 0.75rem; }
  .md\:gap-x-5 { column-gap: 1.25rem; }
  .md\:gap-y-8 { row-gap: 2rem; }
  .md\:my-6 { margin-top: 1.5rem; margin-bottom: 1.5rem; }
  .md\:mb-6 { margin-bottom: 1.5rem; }
  .md\:pb-4 { padding-bottom: 1rem; }
  .md\:py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
  .md\:p-3 { padding: 0.75rem; }
  .md\:text-sm { font-size: 0.875rem; line-height: 1.25rem; }
  .md\:leading-5 { line-height: 1.25rem; }
  .md\:truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Genuinely absent from the dump, which is why the sticky footer bar's 55px
     spacer used to leave a gap on desktop: only layout.css's own media query
     was hiding the bar itself. */
  .md\:hidden { display: none; }
  .md\:block { display: block; }
  .md\:inline-flex { display: inline-flex; }
}

/* ---------------------------------------------------------------------------
   Account sheet (components/layout/AccountDrawer.vue)

   The right-hand slide-out is shadcn's Sheet. Its Radix `data-[state=open]`
   animation classes cannot be reproduced without tailwindcss-animate, so the
   transition itself lives in the component; everything here is the static half
   of that markup which the dump does not carry.
   --------------------------------------------------------------------------- */
.w-3\/4 { width: 75%; }
/* The sheet is narrower than shadcn's default: two thirds of a phone screen and
   never wider than 20rem, so the page stays visible behind the scrim. */
.w-2\/3 { width: 66.666667%; }
.border-l { border-left-width: 1px; }
.flex-row { flex-direction: row; }
.bg-background { background-color: rgb(var(--ds-background) / 1); }
.top-4 { top: 1rem; }
.right-4 { right: 1rem; }
.opacity-70 { opacity: 0.7; }
.hover\:opacity-100:hover { opacity: 1; }
.hover\:opacity-80:hover { opacity: 0.8; }
.hover\:bg-gray-50:hover { background-color: #f9fafb; }
.hover\:bg-gray-100:hover { background-color: #f3f4f6; }
.focus\:outline-none:focus { outline: 2px solid transparent; outline-offset: 2px; }
.focus\:ring-2:focus {
  box-shadow: 0 0 0 var(--tw-ring-offset-width, 2px) var(--tw-ring-offset-color, #fff),
    0 0 0 calc(2px + var(--tw-ring-offset-width, 2px)) var(--tw-ring-color, rgb(var(--ds-primary) / 0.3));
}
.focus\:ring-primary\/30:focus { --tw-ring-color: rgb(var(--ds-primary) / 0.3); }
.focus\:ring-offset-2:focus { --tw-ring-offset-width: 2px; }

@media (min-width: 640px) {
  .sm\:max-w-sm { max-width: 24rem; }
  .sm\:max-w-xs { max-width: 20rem; }
}

/* ---------------------------------------------------------------------------
   Footer (components/Footer.vue)

   The design's footer is a gradient panel with a blurred centre glow, a
   two-column card grid and a translucent bottom bar. Note `.border-t`: the dump
   carries `.border-t-2` but not the 1px form, which is why the old footer's
   `border-t border-gray-200` drew nothing.
   --------------------------------------------------------------------------- */
.border-t { border-top-width: 1px; }
.border-t-4 { border-top-width: 4px; }
.border-t-primary { border-top-color: rgb(var(--ds-primary) / 1); }

.bg-gradient-to-b { background-image: linear-gradient(to bottom, var(--tw-gradient-stops)); }
.from-white {
  --tw-gradient-from: #fff;
  --tw-gradient-to: rgba(255, 255, 255, 0);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.to-slate-100 { --tw-gradient-to: #f1f5f9; }

/* The decorative glow behind the cards. */
.w-\[420px\] { width: 420px; }
.left-1\/2 { left: 50%; }
.-translate-x-1\/2 {
  --tw-translate-x: -50%;
  transform: translate(-50%, var(--tw-translate-y, 0)) rotate(var(--tw-rotate, 0)) skewX(var(--tw-skew-x, 0))
    skewY(var(--tw-skew-y, 0)) scaleX(var(--tw-scale-x, 1)) scaleY(var(--tw-scale-y, 1));
}
.blur-3xl { filter: blur(64px); }

.gap-5 { gap: 1.25rem; }
.gap-x-4 { column-gap: 1rem; }
.gap-y-1\.5 { row-gap: 0.375rem; }
.ml-0\.5 { margin-left: 0.125rem; }
.place-items-center { place-items: center; }
.leading-6 { line-height: 1.5rem; }

/* The social buttons' letter badges are outlined in the darkest slate rather
   than filled with each brand's colour, as the design draws them. */
.border-slate-900 { border-color: #0f172a; }

.ring-slate-200 { --tw-ring-color: #e2e8f0; }
.ring-slate-200\/70 { --tw-ring-color: rgba(226, 232, 240, 0.7); }
.bg-slate-50\/80 { background-color: rgba(248, 250, 252, 0.8); }
.bg-white\/70 { background-color: hsla(0, 0%, 100%, 0.7); }
.backdrop-blur-sm { -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.bg-emerald-100 { background-color: #d1fae5; }

.object-contain { object-fit: contain; }
.object-left { object-position: left; }

.w-48 { width: 12rem; }
.max-w-full { max-width: 100%; }
.min-w-32 { min-width: 8rem; }
.h-\[18px\] { height: 18px; }
.w-\[18px\] { width: 18px; }
.rounded-\[6px\] { border-radius: 6px; }
.-translate-y-px {
  --tw-translate-y: -1px;
  transform: translate(var(--tw-translate-x, 0), -1px) rotate(var(--tw-rotate, 0)) skewX(var(--tw-skew-x, 0))
    skewY(var(--tw-skew-y, 0)) scaleX(var(--tw-scale-x, 1)) scaleY(var(--tw-scale-y, 1));
}

/* The messaging brands' own colours, as the design spells them. */
.bg-\[\#25d366\] { background-color: #25d366; }
.bg-\[\#229ed9\] { background-color: #229ed9; }
.bg-\[\#1d9bf0\] { background-color: #1d9bf0; }

@media (min-width: 768px) {
  .md\:grid-cols-\[minmax\(0\2c 1fr\)_minmax\(320px\2c 400px\)\] {
    grid-template-columns: minmax(0, 1fr) minmax(320px, 400px);
  }
  .md\:items-start { align-items: flex-start; }
  .md\:gap-6 { gap: 1.5rem; }
  .md\:h-11 { height: 2.75rem; }
  .md\:w-11 { width: 2.75rem; }
  .md\:h-12 { height: 3rem; }
  .md\:w-56 { width: 14rem; }
  .md\:min-w-36 { min-width: 9rem; }
  .md\:text-base { font-size: 1rem; line-height: 1.5rem; }
  .md\:text-2xl { font-size: 1.5rem; line-height: 2rem; }
  .md\:leading-7 { line-height: 1.75rem; }
}

/* ===========================================================================
   Latest Orders, the leaderboards and the home page's rank cards.

   Everything below is here for the same reason as the rest of this file: the
   markup these sections are built from comes from a Tailwind build, and the
   frozen dump in tailwindcss.css carries only the 400/500 step of most colour
   scales, no gradient utilities at all, and no arbitrary values.

   Verify with `node scripts/missing-classes.js --from <file.vue>` after copying
   markup from the design - a class with no rule here fails silently.
   =========================================================================== */

/* Palette steps the dump skips. Tailwind v3's own hex values. */
.border-slate-100 { border-color: #f1f5f9; }
.border-slate-300 { border-color: #cbd5e1; }
.bg-slate-50\/70 { background-color: rgba(248, 250, 252, 0.7); }

.border-emerald-100 { border-color: #d1fae5; }
.border-emerald-200 { border-color: #a7f3d0; }
.bg-emerald-50 { background-color: #ecfdf5; }
.text-emerald-700 { color: #047857; }
.text-emerald-800 { color: #065f46; }

.border-sky-200 { border-color: #bae6fd; }
.bg-sky-50 { background-color: #f0f9ff; }
.text-sky-700 { color: #0369a1; }

.border-indigo-200 { border-color: #c7d2fe; }
.bg-indigo-50 { background-color: #eef2ff; }
.text-indigo-700 { color: #4338ca; }

.border-amber-100 { border-color: #fef3c7; }
.border-amber-200 { border-color: #fde68a; }
.bg-amber-50 { background-color: #fffbeb; }
.bg-amber-100 { background-color: #fef3c7; }
.text-amber-600 { color: #d97706; }
.text-amber-700 { color: #b45309; }
.text-amber-800 { color: #92400e; }
.ring-amber-200 { --tw-ring-color: #fde68a; }

.border-rose-200 { border-color: #fecdd3; }
.bg-rose-50 { background-color: #fff1f2; }
.text-rose-700 { color: #be123c; }

.bg-yellow-50 { background-color: #fefce8; }
.text-slate-700 { color: #334155; }
/* ---------------------------------------------------------------------------
   Gradients. The dump initialises --tw-gradient-*-position to empty in its base
   rule but ships no direction or colour-stop utilities, so both halves are here.
   The `to` value on a `from-` class is that colour at zero alpha, which is what
   makes a two-stop gradient with only a `from-` fade out rather than break.
   --------------------------------------------------------------------------- */
.bg-gradient-to-r { background-image: linear-gradient(to right, var(--tw-gradient-stops)); }
.bg-gradient-to-br { background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); }

.from-slate-300 {
  --tw-gradient-from: #cbd5e1 var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(203, 213, 225, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-slate-400 {
  --tw-gradient-from: #94a3b8 var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(148, 163, 184, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-sky-300 {
  --tw-gradient-from: #7dd3fc var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(125, 211, 252, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-rose-400 {
  --tw-gradient-from: #fb7185 var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(251, 113, 133, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-violet-400 {
  --tw-gradient-from: #a78bfa var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(167, 139, 250, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-yellow-400 {
  --tw-gradient-from: #facc15 var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(250, 204, 21, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-amber-300 {
  --tw-gradient-from: #fcd34d var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(252, 211, 77, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-amber-50 {
  --tw-gradient-from: #fffbeb var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(255, 251, 235, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-amber-500 {
  --tw-gradient-from: #f59e0b var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(245, 158, 11, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.via-yellow-50 {
  --tw-gradient-to: rgba(254, 252, 232, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), #fefce8 var(--tw-gradient-via-position),
    var(--tw-gradient-to);
}
.to-white { --tw-gradient-to: #fff var(--tw-gradient-to-position); }
.to-slate-500 { --tw-gradient-to: #64748b var(--tw-gradient-to-position); }
.to-slate-600 { --tw-gradient-to: #475569 var(--tw-gradient-to-position); }
.to-cyan-500 { --tw-gradient-to: #06b6d4 var(--tw-gradient-to-position); }
.to-red-600 { --tw-gradient-to: #dc2626 var(--tw-gradient-to-position); }
.to-purple-600 { --tw-gradient-to: #9333ea var(--tw-gradient-to-position); }
.to-yellow-500 { --tw-gradient-to: #eab308 var(--tw-gradient-to-position); }
.to-amber-600 { --tw-gradient-to: #d97706 var(--tw-gradient-to-position); }
.to-orange-600 { --tw-gradient-to: #ea580c var(--tw-gradient-to-position); }

/* ---------------------------------------------------------------------------
   The live badge's pulse. Tailwind ships `ping` as a keyframe set the dump does
   not include, only animate-spin and animate-pulse.
   --------------------------------------------------------------------------- */
.animate-ping {
  animation: ds-ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
}

@keyframes ds-ping {
  75%,
  100% {
    transform: scale(2);
    opacity: 0;
  }
}

/* Sizes, spacing and the arbitrary grids the order rows and tables are built on. */
.h-11 { height: 2.75rem; }
.w-11 { width: 2.75rem; }
.h-3\.5 { height: 0.875rem; }
.w-3\.5 { width: 0.875rem; }
.mb-8 { margin-bottom: 2rem; }
.ml-auto { margin-left: auto; }
.p-2\.5 { padding: 0.625rem; }
.px-2\.5 { padding-left: 0.625rem; padding-right: 0.625rem; }
.py-0\.5 { padding-top: 0.125rem; padding-bottom: 0.125rem; }
.mt-0\.5 { margin-top: 0.125rem; }
.gap-1\.5 { gap: 0.375rem; }
.leading-tight { line-height: 1.25; }
.opacity-75 { opacity: 0.75; }
.text-\[11px\] { font-size: 11px; line-height: 1rem; }
.w-24 { width: 6rem; }
.grid-cols-\[40px_1fr_auto\] { grid-template-columns: 40px 1fr auto; }
.grid-cols-\[56px_1fr_auto\] { grid-template-columns: 56px 1fr auto; }
.shadow-\[0_12px_40px_rgba\(15\2c 23\2c 42\2c 0\.06\)\] {
  box-shadow: 0 12px 40px rgba(15, 23, 42, 0.06);
}
.shadow-\[0_12px_40px_rgba\(180\2c 130\2c 20\2c 0\.08\)\] {
  box-shadow: 0 12px 40px rgba(180, 130, 20, 0.08);
}

@media (min-width: 768px) {
  .md\:mb-4 { margin-bottom: 1rem; }
  .md\:p-3 { padding: 0.75rem; }
  .md\:p-4 { padding: 1rem; }
  .md\:p-8 { padding: 2rem; }
  .md\:w-12 { width: 3rem; }
  .md\:inline { display: inline; }
  .md\:inline-block { display: inline-block; }
  .md\:space-y-2\.5 > :not([hidden]) ~ :not([hidden]) { margin-top: 0.625rem; }
  .md\:grid-cols-\[48px_1fr_auto_auto\] {
    grid-template-columns: 48px 1fr auto auto;
  }
}
/* ---------------------------------------------------------------------------
   Leaderboards (pages/leaderboard/*, components/store/Leaderboard*.vue)

   The podium is the first markup in the storefront to need a 640px breakpoint
   for anything but a max-width, so most of what follows is the `sm:` half the
   dump's generator never produced.
   --------------------------------------------------------------------------- */
.max-w-4xl { max-width: 56rem; }
.py-10 { padding-top: 2.5rem; padding-bottom: 2.5rem; }
.self-start { align-self: flex-start; }
.top-3 { top: 0.75rem; }
.left-3 { left: 0.75rem; }
.right-3 { right: 0.75rem; }
.border-amber-300 { border-color: #fcd34d; }
.fill-amber-400 { fill: #fbbf24; }
.hover\:bg-amber-50:hover { background-color: #fffbeb; }
.text-\[9px\] { font-size: 9px; line-height: 1rem; }
/* The bronze medal, which the design spells as a hex rather than a palette name. */
.text-\[\#cd7f32\] { color: #cd7f32; }
/* The winner's avatar ring. Same shape as the dump's own ring-1/ring-2. */
.ring-4 {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width, 0px)
    var(--tw-ring-offset-color, #fff);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width, 0px))
    var(--tw-ring-color, rgba(147, 197, 253, 0.5));
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
/* Table row separators: the border width comes from the dump's `divide-y`, only
   the colour is missing. */
.divide-slate-100 > :not([hidden]) ~ :not([hidden]) { border-color: #f1f5f9; }

.from-amber-100\/70 {
  --tw-gradient-from: rgba(254, 243, 199, 0.7) var(--tw-gradient-from-position);
  --tw-gradient-to: rgba(254, 243, 199, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
/* `from-primary to-primary` is a flat fill in the theme colour - the design uses
   a gradient utility for it so the shop's colour can be changed in one place. */
.from-primary {
  --tw-gradient-from: rgb(var(--ds-primary) / 1) var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(var(--ds-primary) / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.to-primary { --tw-gradient-to: rgb(var(--ds-primary) / 1) var(--tw-gradient-to-position); }
.to-amber-500 { --tw-gradient-to: #f59e0b var(--tw-gradient-to-position); }

@media (min-width: 640px) {
  .sm\:block { display: block; }
  .sm\:flex-row { flex-direction: row; }
  .sm\:items-start { align-items: flex-start; }
  .sm\:items-end { align-items: flex-end; }
  .sm\:justify-between { justify-content: space-between; }
  .sm\:self-end { align-self: flex-end; }
  .sm\:py-5 { padding-top: 1.25rem; padding-bottom: 1.25rem; }
  .sm\:py-7 { padding-top: 1.75rem; padding-bottom: 1.75rem; }
  .sm\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Rank | Player | Tier | Points. Below 640px the tier column is hidden and the
     table falls back to the three-track grid in the markup. */
  .sm\:grid-cols-\[56px_1fr_140px_120px\] {
    grid-template-columns: 56px 1fr 140px 120px;
  }
  /* The podium's cards are written second-first-third, the order the design's own
     markup uses, and put back into 1-2-3 here; on a phone they keep DOM order so
     the winner is on top. */
  .sm\:order-1 { order: 1; }
  .sm\:order-2 { order: 2; }
  .sm\:order-3 { order: 3; }
  /* The winner's card stands slightly proud of the other two. */
  .sm\:-translate-y-3 {
    --tw-translate-y: -0.75rem;
    transform: translate(var(--tw-translate-x, 0), -0.75rem) rotate(var(--tw-rotate, 0))
      skewX(var(--tw-skew-x, 0)) skewY(var(--tw-skew-y, 0)) scaleX(var(--tw-scale-x, 1))
      scaleY(var(--tw-scale-y, 1));
  }
}

@media (min-width: 768px) {
  .md\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; }
}

/* The home page's two rank strips (components/store/LeaderboardStrip.vue). */
.space-y-5 > :not([hidden]) ~ :not([hidden]) { margin-top: 1.25rem; }
.text-white\/80 { color: rgba(255, 255, 255, 0.8); }
.hover\:bg-slate-50:hover { background-color: #f8fafc; }

@media (min-width: 768px) {
  .md\:px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
  .md\:text-lg { font-size: 1.125rem; line-height: 1.75rem; }
}

/* DS-APPEND-MARK */
