/* ==========================================================================
   Linker — design system
   --------------------------------------------------------------------------
   One file, ordered: tokens -> reset -> primitives -> components -> layouts
   -> responsive -> motion. Nothing below uses a value that isn't a token.

   Chrome is monochrome on purpose. Valve's rarity spectrum is the only
   saturated colour allowed on screen, so rarity is what the eye finds first.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  color-scheme: dark;

  /* -- Surfaces. Dark UI reads elevation through surface lightness first and
        shadow second, so each level is a real step, not an opacity. --------- */
  --surface-0: #0d0e0f;   /* page */
  --surface-1: #16181a;   /* card, header */
  --surface-2: #1f2225;   /* raised, hover, input */
  --surface-3: #292d31;   /* popover, dropdown, tooltip */
  --surface-inset: #101112;

  --border-subtle:  rgba(255, 255, 255, 0.07);
  --border-default: rgba(255, 255, 255, 0.13);
  --border-strong:  rgba(255, 255, 255, 0.22);

  /* -- Text. Every value clears 4.5:1 on surfaces 0 THROUGH 3, so a token
        stays legible when a card lifts to --surface-2 on hover or a label
        sits inside a --surface-3 popover. Ratios shown against --surface-1. */
  --text-primary:   #f2f4f5;   /* 16.1:1  (12.6:1 on --surface-3) */
  --text-secondary: #a8aeb4;   /*  7.9:1  ( 6.2:1 on --surface-3) */
  --text-tertiary:  #8f969d;   /*  6.0:1  ( 4.6:1 on --surface-3) */
  --text-inverse:   #0d0e0f;

  /* -- Brand. A warm off-white: it can sit at full strength next to seven
        rarity hues without competing with any of them. -------------------- */
  --brand:       #f4f1ec;
  --brand-hover: #ffffff;
  --brand-muted: rgba(244, 241, 236, 0.10);

  /* -- Semantic ------------------------------------------------------------ */
  --success:    #3fb950;
  --success-bg: rgba(63, 185, 80, 0.12);
  --warning:    #d8a336;
  --warning-bg: rgba(216, 163, 54, 0.12);
  --danger:     #f85149;
  --danger-bg:  rgba(248, 81, 73, 0.12);
  --info:       #6ba8f5;
  --info-bg:    rgba(107, 168, 245, 0.12);

  /* -- Rarity. Text-safe values, tone-corrected from Valve's originals so
        every tier clears 4.5:1 on --surface-1 AND on --surface-2 (hover).
        The `-vivid` pair keeps Valve's exact hue for bars and glows, which
        are decorative and only need 3:1. ---------------------------------- */
  --rarity-stock:       #b6bcc2;  --rarity-stock-vivid:       #ded6cc;
  --rarity-consumer:    #b0c3d9;  --rarity-consumer-vivid:    #b0c3d9;
  --rarity-industrial:  #5e98d9;  --rarity-industrial-vivid:  #5e98d9;
  --rarity-milspec:     #6c85ff;  --rarity-milspec-vivid:     #4b69ff;
  --rarity-restricted:  #a472ff;  --rarity-restricted-vivid:  #8847ff;
  --rarity-classified:  #db50ea;  --rarity-classified-vivid:  #d32ce6;
  --rarity-covert:      #ed5d5d;  --rarity-covert-vivid:      #eb4b4b;
  --rarity-contraband:  #e4ae39;  --rarity-contraband-vivid:  #e4ae39;
  --rarity-unknown:     #9da1a9;  --rarity-unknown-vivid:     #9da1a9;

  /* -- Spacing. 4px base. Nothing gets a value off this scale. ------------ */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;

  /* -- Type. Minor third, fluid at the top two steps. --------------------- */
  --font-sans: "Inter", "Inter Fallback", -apple-system, BlinkMacSystemFont,
               "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --text-xs:   0.75rem;    /* 12 */
  --text-sm:   0.875rem;   /* 14 */
  --text-base: 1rem;       /* 16 */
  --text-lg:   1.125rem;   /* 18 */
  --text-xl:   1.5rem;     /* 24 */
  --text-2xl:  clamp(1.75rem, 1.2rem + 2.2vw, 2.5rem);
  --text-3xl:  clamp(2rem, 1.3rem + 3vw, 3rem);

  --leading-tight: 1.15;
  --leading-snug:  1.3;
  --leading-normal: 1.5;
  --leading-relaxed: 1.65;

  --tracking-tight: -0.02em;
  --tracking-wide: 0.06em;

  /* -- Radius. Small and deliberate: this is a reference tool, not a
        consumer app. The old uniform 14px is what made it read "soft". ---- */
  --radius-sm:   6px;
  --radius-md:  10px;
  --radius-lg:  16px;
  --radius-full: 9999px;

  /* -- Elevation ----------------------------------------------------------- */
  --shadow-sm:      0 1px 2px rgba(0, 0, 0, 0.40);
  --shadow-md:      0 2px 8px rgba(0, 0, 0, 0.45);
  --shadow-lg:      0 8px 24px rgba(0, 0, 0, 0.50);
  --shadow-popover: 0 12px 32px rgba(0, 0, 0, 0.60);

  /* -- Motion. Fast, property-specific, easing out. ----------------------- */
  --duration-fast: 120ms;
  --duration-base: 180ms;
  --duration-slow: 280ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);

  /* -- Layout -------------------------------------------------------------- */
  --gutter: var(--space-4);
  --max-width: 1560px;
  --header-height: 60px;

  /* Cards grow with the viewport instead of the margins growing.
     At 2560px this fills the screen; at 390px it drops to two columns. */
  --card-min: clamp(150px, 13vw, 210px);
  --item-min: clamp(230px, 19vw, 290px);
}

/* Metric-matched fallback so a cold load doesn't reflow when Inter arrives.
   size-adjust is measured, not guessed: Inter's advance width for a
   representative string is 105.6% of Arial's at the same size. Getting this
   wrong shows up as horizontal drift on inline links inside wrapped text.
   Ship real Inter woff2 files at deploy time and this becomes belt-and-braces. */
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial");
  size-adjust: 105.6%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

/* --------------------------------------------------------------------------
   2. Reset + base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  /* The old build had no overflow guard, so a nav wider than the viewport
     inflated the document width and clipped the right column of every grid. */
  overflow-x: hidden;
  background: var(--surface-0);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 { margin: 0; font-weight: 600; }
h1 { font-size: var(--text-2xl); line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); font-weight: 700; }
h2 { font-size: var(--text-xl); line-height: var(--leading-snug); letter-spacing: var(--tracking-tight); }
h3 { font-size: var(--text-lg); line-height: var(--leading-snug); }
h4 { font-size: var(--text-base); line-height: var(--leading-snug); }
h5, h6 { font-size: var(--text-sm); line-height: var(--leading-snug); }

p { margin: 0 0 var(--space-4); max-width: 68ch; }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0; padding: 0; }

a { color: inherit; }

img, svg { display: block; max-width: 100%; }

button, input, select, textarea { font: inherit; color: inherit; }

table { border-collapse: collapse; width: 100%; }

:target { scroll-margin-top: calc(var(--header-height) + var(--space-6)); }

/* Focus is global, non-negotiable, and never removed without a replacement.
   The old stylesheet had zero :focus rules and an explicit outline:none. */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: rgba(244, 241, 236, 0.22); }

/* --------------------------------------------------------------------------
   3. Utilities
   -------------------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Header and content share one gutter token, so the wordmark and the page
   title finally sit on the same vertical line. */

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: var(--space-2);
  z-index: 300;
  transform: translateY(-200%);
  padding: var(--space-2) var(--space-4);
  background: var(--brand);
  color: var(--text-inverse);
  font-size: var(--text-sm);
  font-weight: 600;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: transform var(--duration-base) var(--ease-out);
}
.skip-link:focus { transform: translateY(0); }

.stack > * + * { margin-top: var(--flow, var(--space-4)); }
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.spacer { flex: 1 1 auto; }
.text-secondary { color: var(--text-secondary); }
.text-tertiary  { color: var(--text-tertiary); }
.nums { font-variant-numeric: tabular-nums; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clamp-2 {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  line-clamp: 2; overflow: hidden;
}

.eyebrow {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* --------------------------------------------------------------------------
   4. Header + navigation
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--surface-1) 82%, transparent);
  backdrop-filter: blur(12px) saturate(140%);
  border-bottom: 1px solid var(--border-subtle);
}
@supports not (backdrop-filter: blur(1px)) {
  .site-header { background: var(--surface-1); }
}

.header-bar {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--header-height);
}
/* Every child must be allowed to shrink below its content width, or the row
   sets a document width wider than the viewport — which is precisely how the
   previous build clipped the right column of every grid on mobile. */
.header-bar > * { min-width: 0; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  /* The wordmark never truncates — the search field absorbs the squeeze. */
  flex: 0 0 auto;
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  color: var(--text-primary);
  text-decoration: none;
  border-radius: var(--radius-sm);
}
.brand-mark { width: 26px; height: 26px; flex: none; }
.brand-name { line-height: 1; white-space: nowrap; }
.primary-nav { display: none; }
.primary-nav ul { display: flex; align-items: center; gap: var(--space-1); list-style: none; }

.nav-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--duration-fast) var(--ease-out),
              background-color var(--duration-fast) var(--ease-out);
}
.nav-link:hover { color: var(--text-primary); background: var(--brand-muted); }
.nav-link[aria-current="page"] {
  color: var(--text-primary);
  background: var(--surface-2);
  font-weight: 600;
}
.nav-link .count {
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
}
.nav-link[aria-current="page"] .count { color: var(--text-secondary); }

.header-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-left: auto;
  flex: 1 1 auto;
  min-width: 0;
}

/* Mobile drawer ------------------------------------------------------------ */

.nav-toggle { display: inline-flex; }

.mobile-nav {
  position: fixed;
  inset: var(--header-height) 0 0 0;
  z-index: 90;
  display: grid;
  align-content: start;
  gap: var(--space-1);
  padding: var(--space-4) var(--gutter) var(--space-8);
  background: var(--surface-0);
  border-top: 1px solid var(--border-subtle);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.mobile-nav[hidden] { display: none; }
.mobile-nav a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-3);
  min-height: 48px;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--text-primary);
  text-decoration: none;
}
.mobile-nav a:hover { background: var(--surface-1); }
.mobile-nav a[aria-current="page"] { background: var(--surface-1); border-color: var(--border-default); }
.mobile-nav .count { color: var(--text-tertiary); font-variant-numeric: tabular-nums; font-size: var(--text-sm); }
.mobile-nav hr { border: 0; border-top: 1px solid var(--border-subtle); margin: var(--space-3) 0; }

body.nav-open { overflow: hidden; }

/* --------------------------------------------------------------------------
   5. Search combobox
   -------------------------------------------------------------------------- */

.search {
  position: relative;
  /* A flex-basis of 0 rather than auto: an <input> carries an intrinsic size
     of about 20 characters, and `auto` would let that dictate the header's
     minimum width. */
  flex: 1 1 0;
  min-width: 0;
  max-width: 420px;
}
.search-field {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-inline: var(--space-3);
  background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  transition: border-color var(--duration-fast) var(--ease-out),
              background-color var(--duration-fast) var(--ease-out);
}
.search-field:hover { border-color: var(--border-default); }
.search-field:focus-within {
  border-color: var(--border-strong);
  background: var(--surface-3);
  outline: 2px solid var(--brand);
  outline-offset: 1px;
}
.search-field .icon { flex: none; color: var(--text-tertiary); }
.search-field { min-width: 0; }
.search-field input {
  flex: 1 1 0;
  width: 100%;
  min-width: 0;
  height: 38px;
  background: transparent;
  border: 0;
  outline: none;
  font-size: var(--text-sm);
}
.search-field input::placeholder { color: var(--text-tertiary); }
.search-field input::-webkit-search-cancel-button { display: none; }

.search-clear,
.search-hint {
  flex: none;
  display: none;
  align-items: center;
  justify-content: center;
}
.search-hint {
  padding: 2px var(--space-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-family: var(--font-mono);
  color: var(--text-tertiary);
  line-height: 1.4;
}
.search-field:not(:focus-within) .search-hint { display: inline-flex; }
.search.has-value .search-clear { display: inline-flex; }
.search.has-value .search-hint { display: none; }

.search-clear {
  width: 24px; height: 24px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--radius-full);
  color: var(--text-tertiary);
  cursor: pointer;
}
.search-clear:hover { color: var(--text-primary); background: var(--brand-muted); }

/* Popover sits ABOVE the surfaces behind it — the old dropdown was set to the
   page background, i.e. darker than the card and navbar it floated over. */
.search-results {
  position: absolute;
  top: calc(100% + var(--space-2));
  inset-inline: 0;
  z-index: 200;
  max-height: min(60vh, 420px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-1);
  background: var(--surface-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-popover);
  list-style: none;
}
.search-results[hidden] { display: none; }

.search-option {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
  scroll-margin: var(--space-1);
}
.search-option[aria-selected="true"] { background: var(--brand-muted); }
.search-option img {
  width: 40px; height: 30px;
  flex: none;
  object-fit: contain;
  border-radius: var(--radius-sm);
  /* background: var(--surface-inset); */
}
.search-option .name {
  min-width: 0;
  flex: 1 1 auto;
  font-size: var(--text-sm);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.search-option .name mark {
  background: transparent;
  color: var(--brand);
  font-weight: 700;
}

.search-empty { padding: var(--space-5) var(--space-4); text-align: center; }
.search-empty .title { font-size: var(--text-sm); font-weight: 600; }
.search-empty .hint { font-size: var(--text-xs); color: var(--text-tertiary); margin-top: var(--space-1); }

.search-loading {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-tertiary);
}

/* --------------------------------------------------------------------------
   6. Buttons
   -------------------------------------------------------------------------- */

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--text-primary);
  --btn-border: var(--border-default);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: 0 var(--space-4);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.btn:hover { --btn-bg: var(--surface-2); --btn-border: var(--border-strong); }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

.btn-primary { --btn-bg: var(--brand); --btn-fg: var(--text-inverse); --btn-border: var(--brand); }
.btn-primary:hover { --btn-bg: var(--brand-hover); --btn-border: var(--brand-hover); }

.btn-ghost { --btn-border: transparent; }
.btn-ghost:hover { --btn-bg: var(--brand-muted); --btn-border: transparent; }

.btn-danger { --btn-fg: var(--danger); --btn-border: color-mix(in srgb, var(--danger) 40%, transparent); }
.btn-danger:hover { --btn-bg: var(--danger-bg); --btn-border: var(--danger); }

.btn-sm { min-height: 32px; padding: 0 var(--space-3); font-size: var(--text-xs); }
.btn-lg { min-height: 48px; padding: 0 var(--space-5); font-size: var(--text-base); }

.btn-icon { width: 40px; min-height: 40px; padding: 0; }
.btn-icon.btn-sm { width: 32px; min-height: 32px; }

.btn[data-loading="true"] { color: transparent; position: relative; pointer-events: none; }
.btn[data-loading="true"]::after {
  content: "";
  position: absolute;
  width: 16px; height: 16px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--btn-fg);
  animation: spin 700ms linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* External destinations announce themselves. The old build wrapped the page
   h1 in a bare link to Steam with no icon, no underline and no warning. */
.external-icon { flex: none; opacity: 0.7; }

/* --------------------------------------------------------------------------
   7. Badges, chips, rarity
   -------------------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  background: var(--surface-2);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.5;
  color: var(--text-secondary);
  white-space: nowrap;
}
.badge-new { color: var(--success); border-color: color-mix(in srgb, var(--success) 40%, transparent); background: var(--success-bg); }
.badge-solid { background: var(--brand); color: var(--text-inverse); border-color: var(--brand); }

/* Rarity is never colour alone: a swatch AND a word, always. */
.rarity {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--rarity, var(--text-secondary));
  white-space: nowrap;
}
.rarity::before {
  content: "";
  width: 8px; height: 8px;
  flex: none;
  border-radius: 2px;
  background: var(--rarity-vivid, var(--rarity, currentColor));
}

.rarity-bar {
  height: 3px;
  border-radius: var(--radius-full);
  background: var(--rarity-vivid, var(--border-default));
}

/* Chips — the wear selector. Five of these replace a ten-cell table whose
   two columns contained the same five strings. */
.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 32px;
  padding: 0 var(--space-3);
  background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.chip:hover { background: var(--surface-3); border-color: var(--border-strong); color: var(--text-primary); }
.chip[aria-pressed="true"], .chip[data-active="true"] {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--text-inverse);
}
.chip[disabled], .chip[aria-disabled="true"] { opacity: 0.4; pointer-events: none; }
/* A real colour, not an opacity — opacity would drop this below AA. */
.chip .count { margin-left: var(--space-2); color: var(--text-tertiary); font-weight: 500; }
.chip[aria-pressed="true"] .count, .chip[data-active="true"] .count { color: inherit; opacity: 0.7; }

.chip-row { display: flex; flex-wrap: wrap; gap: var(--space-1); }

/* Chips carrying arbitrary content names — "Budapest 2025 Mirage Souvenir
   Package" is 38 characters and would otherwise push the card past the
   viewport. Truncated visually; the full name stays in title + aria-label. */
.source-chips { list-style: none; }
.source-chips li { min-width: 0; max-width: 100%; }
.source-chips .chip {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 30px;
  text-align: left;
}

/* --------------------------------------------------------------------------
   8. Card primitive
   -------------------------------------------------------------------------- */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  transition: background-color var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}
/* Hover whispers: a surface step and a border step. No accent ring. */
.card:hover { background: var(--surface-2); border-color: var(--border-default); box-shadow: var(--shadow-md); }
.card:has(a:focus-visible) { border-color: var(--border-strong); }

/* Stretched-link pattern: the whole card is the target, but only one real
   anchor exists, so screen readers and tab order stay sane. */
.card-link::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Above the media image, which is absolutely positioned at z-index 1 —
     without this the artwork sits on top of the stretched link and swallows
     the click, leaving only the title text clickable. */
  z-index: 2;
  border-radius: inherit;
}
.card-link { text-decoration: none; color: inherit; }
.card-link:focus-visible { outline: none; }
.card:has(.card-link:focus-visible) {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
/* Anything that must stay clickable inside a stretched-link card — so it has
   to sit above the stretched ::after, not just above the image. */
.card .above { position: relative; z-index: 3; }

/* Fixed media boxes. Every image gets an aspect ratio, which removes the
   layout shift AND makes card titles baseline-align across a row. */
.card-media {
  position: relative;
  overflow: hidden;
  border-radius: calc(var(--radius-md) - 1px) calc(var(--radius-md) - 1px) 0 0;
  background: var(--surface-inset);
}
/* Absolutely filled, not laid out.
   `height: 100%` on an in-flow child of an aspect-ratio box is a cyclic
   dependency: the box's height comes from the ratio, the child asks for 100%
   of it, and the browser resolved the child a few pixels TALLER than the box
   — which `overflow: hidden` then clipped off the bottom of every render.
   Absolute inset:0 sizes against the padding box directly, so the image can
   never exceed it. z-index lifts it over the rarity wash. */
.card-media img {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%; height: 100%;
  object-fit: contain;
  padding: var(--space-3);
  transition: transform var(--duration-slow) var(--ease-out);
}
.card:hover .card-media img { transform: scale(1.04); }

.card-media.ratio-4-3 { aspect-ratio: 4 / 3; }
.card-media.ratio-1-1 { aspect-ratio: 1 / 1; }

/* Weapon renders sit inside a lot of transparent padding. A rarity-tinted
   radial wash turns that dead area into the rarity signal. */
.card-media[data-rarity]::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 62%,
              color-mix(in srgb, var(--rarity-vivid) 22%, transparent) 0%,
              transparent 68%);
  opacity: 0.75;
  transition: opacity var(--duration-base) var(--ease-out);
}
.card:hover .card-media[data-rarity]::before { opacity: 1; }

.card-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4) var(--space-4);
  flex: 1 1 auto;
}
.card-title {
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: var(--leading-snug);
  color: var(--text-primary);
}
.card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  margin-top: auto;
}
/* Separator dot, used wherever inline metadata is chained. */
.dot::before { content: "·"; margin-right: var(--space-2); color: var(--text-tertiary); }

.card-flag {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  z-index: 2;
}

/* --------------------------------------------------------------------------
   9. Grids
   -------------------------------------------------------------------------- */

.grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(var(--card-min), 1fr));
}
.grid-items { --card-min: var(--item-min); }

/* --------------------------------------------------------------------------
   10. Page furniture
   -------------------------------------------------------------------------- */

/* The content column IS a wrap — header, main and footer therefore share one
   gutter token, which is what finally puts the wordmark and the page <h1> on
   the same vertical line. */
.content {
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-block: var(--space-6) var(--space-9);
}

.breadcrumb { font-size: var(--text-sm); color: var(--text-tertiary); }
.breadcrumb ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); list-style: none; }
.breadcrumb a { color: var(--text-secondary); text-decoration: none; border-radius: var(--radius-sm); }
.breadcrumb a:hover { color: var(--text-primary); text-decoration: underline; }
.breadcrumb li + li::before { content: "/"; margin-right: var(--space-2); color: var(--border-strong); }
.breadcrumb [aria-current="page"] { color: var(--text-secondary); }

.page-head { display: grid; gap: var(--space-3); margin-bottom: var(--space-6); }
.page-head .lede {
  font-size: var(--text-base);
  color: var(--text-secondary);
  max-width: 62ch;
  margin: 0;
}
.page-head .title-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3);
}
.page-head .count {
  font-size: var(--text-sm);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
}

.section { margin-top: var(--space-8); }
.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.section-head h2 { font-size: var(--text-lg); }
.section-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 24px;   /* WCAG 2.2 AA 2.5.8 — standalone, so not exempt */
  white-space: nowrap;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-secondary);
  text-decoration: none;
  border-radius: var(--radius-sm);
}
.section-link:hover { color: var(--text-primary); text-decoration: underline; }
/* Inside running copy it should read as part of the sentence, not as a
   heading-scale link. */
p .section-link { font-size: inherit; font-weight: 600; }

/* --------------------------------------------------------------------------
   11. Detail page
   -------------------------------------------------------------------------- */

.detail-head {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--border-subtle);
  margin-bottom: var(--space-6);
}
.detail-art {
  width: min(100%, 220px);
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
  background: var(--surface-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.detail-art { position: relative; }
.detail-art img {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%; height: 100%;
  object-fit: contain;
  padding: var(--space-3);
}

.detail-info { display: grid; gap: var(--space-4); align-content: start; }
.detail-facts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/* The skin page's hero render gets the same rarity wash as its card. */
.skin-art { width: min(100%, 340px); aspect-ratio: 4 / 3; position: relative; }
.skin-art::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 60%,
              color-mix(in srgb, var(--rarity-vivid) 24%, transparent) 0%,
              transparent 70%);
}
/* No `position: relative` override here — it would beat `.detail-art img`'s
   absolute fill and let the render overflow its box again. The z-index on the
   absolute rule already lifts it above the rarity wash. */

/* Item card ---------------------------------------------------------------- */

.item-card .rarity-bar { border-radius: var(--radius-md) var(--radius-md) 0 0; }
.item-card .card-body { gap: var(--space-3); }
.item-card .item-weapon { font-size: var(--text-xs); }
.item-card .item-name,
.skin-tile .item-name {
  font-size: var(--text-base);
  font-weight: 600;
  line-height: var(--leading-snug);
  color: var(--text-primary);
}
.skin-tile .rarity-bar { border-radius: var(--radius-md) var(--radius-md) 0 0; }
.skin-tile .card-body { gap: var(--space-2); }

/* --------------------------------------------------------------------------
   Wear links — the product itself

   One labelled row per finish, every destination visible. The previous build
   hid StatTrak behind a page-level toggle; before that it was a 2x5 table in
   which both columns rendered the same five words. The defect was never the
   link COUNT — it was that the links were undifferentiated, unlabelled and
   ~26px tall. Labelled rows fix all three and keep every destination.
   -------------------------------------------------------------------------- */

.wear-block { display: grid; gap: var(--space-2); }
.wear-block-lg { gap: var(--space-3); max-width: 34rem; }

.wear-row { display: grid; gap: var(--space-1); }
.wear-row-label {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.wear-links { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.wear-links .chip {
  flex: 1 1 auto;
  min-width: 44px;
  padding-inline: var(--space-2);
}
.wear-block-lg .wear-links .chip { min-height: 40px; min-width: 56px; font-size: var(--text-sm); }

.no-wears { font-size: var(--text-xs); color: var(--text-tertiary); }

/* --------------------------------------------------------------------------
   Wear-range bar

   The wear chips only say WHICH tiers a skin can be — not where inside them.
   Two skins can both list all five tiers while one caps at 0.38 float and the
   other reaches 1.0; the chips look identical, the skins don't wear anything
   alike. This renders the real float span against the five fixed tier
   boundaries so that difference is visible without reading two numbers.

   Two rows (labels, then track) share the same per-segment widths rather than
   one row with text over the fill — text sitting on top of an opaque colour
   fill only stays legible for one of the two segments it crosses.
   -------------------------------------------------------------------------- */

.wear-range { margin-bottom: var(--space-4); max-width: 34rem; }
.wear-range .wear-row-label { margin-bottom: var(--space-2); }

.wear-range-labels { display: flex; margin-bottom: var(--space-1); }
.wear-range-labels span {
  flex: none;
  overflow: hidden;
  font-size: var(--text-xs);
  font-weight: 600;
  text-align: center;
  color: var(--text-tertiary);
  white-space: nowrap;
}

.wear-range-track {
  position: relative;
  display: flex;
  height: 20px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--surface-2);
  border: 1px solid var(--border-subtle);
}
/* position + z-index so the divider stays visible over the fill: an absolutely
   positioned sibling paints above a static one by default, which buried every
   boundary line the fill happened to cross.

   The divider itself is a light+dark pair, not one tone: the fill is any of
   seven rarity colours, from near-white (Consumer) to near-black-on-dark
   (nothing, they're all mid-bright) — measured contrast for a single white
   line was as low as 1.40:1 against Consumer and 1.48:1 against Contraband,
   and a single black line was 1.20:1 against the empty (unfilled) track.
   Pairing them means whichever side is weak, the other carries it — worst
   case across all seven fills plus the empty track came out at 2.7-3:1. */
.wear-range-seg {
  position: relative;
  z-index: 1;
  flex: none;
  height: 100%;
  border-right: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow: 1px 0 0 rgba(0, 0, 0, 0.55);
}
.wear-range-seg:last-child { border-right: 0; box-shadow: none; }

/* --rarity-vivid is already set on the ancestor via rarity_style(), same
   token the card's rarity bar and pill use. */
.wear-range-fill {
  position: absolute;
  inset-block: 0;
  background: var(--rarity-vivid, var(--brand));
}

.wear-range-bounds {
  margin: var(--space-1) 0 0;
  font-size: var(--text-xs);
  color: var(--text-secondary);
}

/* Below ~360px even 2-character tier labels crowd the narrowest segments
   (FN/MW/WW can be under 30px wide); the track and the numeric bounds still
   carry the same information without them. */
@media (max-width: 22.5em) {
  .wear-range-labels { display: none; }
}

/* Sticker finishes are links like everything else; the preview is an
   enhancement layered on hover and focus, never the only way to see one. */
.variant-chip { gap: var(--space-2); }
.variant-chip::before {
  content: "";
  width: 8px; height: 8px;
  flex: none;
  border-radius: 2px;
  background: var(--rarity-vivid, currentColor);
}

/* One line of orienting copy above an item grid. */
.wear-key {
  font-size: var(--text-xs);
  line-height: var(--leading-normal);
  margin-bottom: var(--space-5);
  max-width: 80ch;
}

/* --------------------------------------------------------------------------
   Freshness

   Speed of update is the value proposition, so it is stated in the chrome
   rather than implied by card dates. The dot is the only always-on colour
   outside the rarity system — it earns that by being the one live signal on
   the site.
   -------------------------------------------------------------------------- */

.freshness {
  display: none;   /* header is too tight below 1024px; the home page and the
                      footer carry it there instead */
  align-items: center;
  gap: var(--space-2);
  flex: none;
  margin: 0;
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
  white-space: nowrap;
}
/* The header indicator is hidden below 1024px, so the home page carries the
   claim in running copy at every width — it is the product's whole pitch and
   must not be desktop-only. */
.page-freshness { display: flex; align-items: baseline; gap: var(--space-2); }
.page-freshness time { color: var(--text-primary); font-weight: 600; }

.freshness-dot {
  /* inline-block, not inline: inside a heading it has no flex parent to make
     width and height apply, and it renders as a sliver. */
  display: inline-block;
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 16%, transparent);
}

/* --------------------------------------------------------------------------
   List controls — one select, and only because A–Z is how you find a known
   name without searching. No filter, no pagination, no view toggle.
   -------------------------------------------------------------------------- */

.list-controls { display: flex; gap: var(--space-2); margin-bottom: var(--space-5); }

.select {
  height: 36px;
  padding: 0 var(--space-6) 0 var(--space-3);
  background: var(--surface-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-primary);
  cursor: pointer;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23a8aeb4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-2) center;
  transition: border-color var(--duration-fast) var(--ease-out);
}
.select:hover { border-color: var(--border-default); }

/* Skin tiles are image + name only, so they pack tighter than item cards. */
.grid-skins { --card-min: clamp(170px, 14vw, 230px); }

/* Weapon index tiles */
.kind-grid {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.kind-card {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-4);
  background: var(--surface-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: background-color var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-out);
}
.kind-card:hover { background: var(--surface-2); border-color: var(--border-default); }
.kind-card .kind-count {
  font-size: var(--text-xl);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-tight);
}
.kind-card .kind-label { font-size: var(--text-sm); font-weight: 600; color: var(--text-primary); }
.kind-card .kind-blurb { font-size: var(--text-xs); color: var(--text-tertiary); line-height: var(--leading-normal); }

/* --------------------------------------------------------------------------
   14. States — empty, error, loading
   -------------------------------------------------------------------------- */

.state {
  display: grid;
  justify-items: center;
  gap: var(--space-3);
  padding: var(--space-9) var(--space-5);
  text-align: center;
  background: var(--surface-1);
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-lg);
}
.state .state-icon {
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  border-radius: var(--radius-full);
  background: var(--surface-2);
  color: var(--text-tertiary);
}
.state h2 { font-size: var(--text-lg); }
.state p { color: var(--text-secondary); max-width: 44ch; margin: 0; }
.state .actions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: center; margin-top: var(--space-2); }

.alert {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  font-size: var(--text-sm);
}
.alert .icon { flex: none; margin-top: 2px; }
.alert-title { font-weight: 600; margin-bottom: var(--space-1); }
.alert-error { border-color: color-mix(in srgb, var(--danger) 40%, transparent); background: var(--danger-bg); }
.alert-error .icon { color: var(--danger); }
.alert-info { border-color: color-mix(in srgb, var(--info) 35%, transparent); background: var(--info-bg); }
.alert-info .icon { color: var(--info); }
.alert-warning { border-color: color-mix(in srgb, var(--warning) 40%, transparent); background: var(--warning-bg); }
.alert-warning .icon { color: var(--warning); }

.skeleton {
  background: linear-gradient(90deg, var(--surface-1) 25%, var(--surface-2) 37%, var(--surface-1) 63%);
  background-size: 400% 100%;
  border-radius: var(--radius-sm);
  animation: shimmer 1.4s ease-in-out infinite;
}
@keyframes shimmer { to { background-position: -135% 0; } }

.spinner {
  width: 16px; height: 16px;
  border: 2px solid var(--border-strong);
  border-top-color: var(--text-primary);
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}

/* --------------------------------------------------------------------------
   15. Tooltip
   -------------------------------------------------------------------------- */

.tooltip { position: relative; }
.tooltip > [role="tooltip"] {
  position: absolute;
  bottom: calc(100% + var(--space-2));
  left: 50%;
  translate: -50% 4px;
  z-index: 210;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-popover);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--text-primary);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-fast) var(--ease-out),
              translate var(--duration-fast) var(--ease-out);
}
.tooltip:hover > [role="tooltip"],
.tooltip:focus-within > [role="tooltip"] { opacity: 1; translate: -50% 0; }

/* --------------------------------------------------------------------------
   17. Prose (about, help copy)
   -------------------------------------------------------------------------- */

.prose { max-width: 68ch; }
.prose h2 { margin-top: var(--space-7); margin-bottom: var(--space-3); }
.prose h3 { margin-top: var(--space-5); margin-bottom: var(--space-2); }
.prose p, .prose li { color: var(--text-secondary); line-height: var(--leading-relaxed); }
.prose ul, .prose ol { padding-left: var(--space-5); margin-bottom: var(--space-4); }
.prose li { margin-bottom: var(--space-2); }
.prose a { color: var(--text-primary); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--border-strong); }
.prose a:hover { text-decoration-color: currentColor; }
.prose strong { color: var(--text-primary); }

/* --------------------------------------------------------------------------
   18. Footer
   -------------------------------------------------------------------------- */

.site-footer {
  margin-top: var(--space-9);
  padding-block: var(--space-7) var(--space-8);
  border-top: 1px solid var(--border-subtle);
  background: var(--surface-1);
  font-size: var(--text-sm);
}
.footer-grid {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
}
.footer-brand { display: grid; gap: var(--space-3); max-width: 34ch; }
.footer-brand p { font-size: var(--text-sm); color: var(--text-secondary); margin: 0; }
.footer-col h2 {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: var(--space-3);
}
.footer-col ul { list-style: none; display: grid; gap: var(--space-2); }
.footer-col a {
  color: var(--text-secondary);
  text-decoration: none;
  border-radius: var(--radius-sm);
}
.footer-col a:hover { color: var(--text-primary); text-decoration: underline; }
.footer-legal {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-subtle);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}
.footer-legal p { margin: 0; max-width: 80ch; }

/* --------------------------------------------------------------------------
   19. Responsive — mobile first, four deliberate breakpoints
   -------------------------------------------------------------------------- */

/* >= 480px — two comfortable columns, wordmark gains its descriptor */
@media (min-width: 30em) {
  :root { --gutter: var(--space-5); }
}

/* >= 768px — tablet: detail page splits into art + info */
@media (min-width: 48em) {
  .detail-head { grid-template-columns: 220px 1fr; align-items: start; gap: var(--space-6); }
  /* A weapon render is 16:10, so a 220px column leaves it 137px tall — too
     small to be the hero of its own page. Container art is 4:3 and fine. */
  .detail-head:has(.skin-art) { grid-template-columns: 340px 1fr; }
  .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; }
  .search-field input { height: 40px; }
}

/* >= 1024px — desktop: real nav replaces the drawer, freshness joins the
   header. Below this the header has no room for it, so the home page and the
   footer carry the signal instead. */
@media (min-width: 64em) {
  :root { --header-height: 64px; --gutter: var(--space-6); }
  .primary-nav { display: block; }
  .nav-toggle { display: none; }
  .mobile-nav { display: none !important; }
  .header-actions { margin-left: 0; }
  .search { margin-left: auto; }
  .freshness { display: flex; }
}

/* < 1600px — the counts are the first thing to go when the row gets tight */
@media (max-width: 99.99em) {
  .nav-link .count { display: none; }
}

/* >= 1600px — room for per-kind counts in the nav itself */
@media (min-width: 100em) {
  .nav-link .count { display: inline; }
  .content { padding-block: var(--space-7) var(--space-9); }
}

/* Ultrawide — the grid keeps filling; only the reading column is capped. */
@media (min-width: 120em) {
  :root { --max-width: 1800px; }
}

/* Coarse pointers get larger targets than the 24px WCAG floor. */
@media (pointer: coarse) {
  .chip, .variant-btn, .segmented button { min-height: 40px; }
  .page-btn { min-width: 44px; min-height: 44px; }
}

/* --------------------------------------------------------------------------
   20. Motion preferences
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .card:hover .card-media img { transform: none; }
  .kind-card:hover { transform: none; }
}

@media (prefers-contrast: more) {
  :root {
    --border-subtle: rgba(255, 255, 255, 0.18);
    --border-default: rgba(255, 255, 255, 0.32);
    --border-strong: rgba(255, 255, 255, 0.45);
    --text-secondary: #c3c9ce;
    --text-tertiary: #a8aeb4;
  }
  .card { border-color: var(--border-default); }
}

@media print {
  .site-header, .site-footer, .toolbar, .pagination, .skip-link { display: none; }
  body { background: #fff; color: #000; }
  .card { border: 1px solid #ccc; }
}
