/* ==========================================================================
   LewdDex — lewddex.css · v1 · 2026-10-06
   One stylesheet for every server-rendered page. Mobile-first. Dark only.
   Hooks kept from the placeholder template:
     body > header · main · body > footer · .grid > .card · .tags > .tag · .ad
   Added hooks (all shown on components.html):
     .ad > .slot (exact-size box the network fills) · .card--row + .grid--feed
     (updated feed) · .layout + .rail (desktop two-column) · .pager · .facts ·
     .versions · .strip > .shot · dialog.lightbox · .browse > .entry
   ========================================================================== */

/* 1. Tokens ------------------------------------------------------------- */
:root {
  color-scheme: dark;

  /* Surfaces — cool near-black, chroma ≈ 0.01 so the covers carry the colour */
  --bg:        #0e1013;   /* page */
  --surface:   #15181d;   /* header, footer, ad wells, fact panels */
  --surface-2: #1c2026;   /* cover fallback, hover fills */
  --surface-3: #242931;   /* pressed, skeleton */
  --line:      #262b33;   /* hairlines */
  --line-2:    #353c47;   /* emphasised borders, dashed ad slots */

  /* Ink — every text pairing ≥ 4.5:1 on --bg and --surface */
  --ink:   #edeff3;
  --ink-2: #aab1bd;
  --ink-3: #7d8694;       /* meta, labels (4.9:1 on --surface) */
  --ink-4: #4b5361;       /* disabled / decorative only — never body text */

  /* The one accent — amber, oklch(82% 0.14 80). Stars, brand, primary CTA, focus. */
  --accent:      #f2b84b;
  --accent-ink:  #231a05;
  --accent-soft: rgba(242, 184, 75, 0.12);

  /* Semantic — status dots only */
  --ok:  #7fcf8a;
  --bad: #e07a7a;

  /* Type — system stack, no webfonts (47% of traffic is on slow links).
     Latin, Cyrillic and CJK all fall through to platform fonts. */
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --fs-0: 11px;   /* kickers, ad labels */
  --fs-1: 12px;   /* card meta, dates */
  --fs-2: 13px;   /* tags, secondary */
  --fs-3: 14px;   /* body, card titles */
  --fs-4: 16px;   /* lede, byline */
  --fs-5: 18px;   /* h2 */
  --fs-6: 22px;   /* h1 — game page */
  --fs-7: 26px;   /* h1 — listing / home */
  --lh:   1.45;
  --lh-tight: 1.2;

  /* Space — 4px base */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 20px; --s-6: 24px; --s-7: 32px; --s-8: 48px;

  /* Radii */
  --r-1: 4px; --r-2: 6px; --r-3: 10px; --r-pill: 999px;

  /* Layout */
  --gutter: 12px;
  --page-max: 1360px;
  --rail: 326px;          /* desktop ad rail = 300px MREC + well padding 2×12 + border 2×1 */
  --cover-ratio: 16 / 9;  /* every cover and screenshot box */
  --tap: 44px;            /* minimum touch target */
}
@media (min-width: 640px)  { :root { --gutter: 20px; --fs-5: 20px; --fs-6: 28px; --fs-7: 32px; } }
@media (min-width: 1024px) { :root { --gutter: 32px; } }

/* 2. Base --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { background: var(--bg); -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--bg); color: var(--ink); font: var(--fs-3)/var(--lh) var(--font); text-wrap: pretty; }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
a:hover { color: var(--accent); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
::selection { background: var(--accent); color: var(--accent-ink); }
h1, h2, h3 { margin: 0; line-height: var(--lh-tight); letter-spacing: -0.015em; text-wrap: balance; overflow-wrap: anywhere; }
h1 { font-size: var(--fs-7); font-weight: 700; }
h2 { font-size: var(--fs-5); font-weight: 600; }
p, dl, dd { margin: 0; }
button { font: inherit; color: inherit; }
.ver, code { font-family: var(--mono); font-size: 0.93em; }
.muted { color: var(--ink-3); }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.wrap { max-width: var(--page-max); margin: 0 auto; padding-left: var(--gutter); padding-right: var(--gutter); }

/* 3. Header / nav -------------------------------------------------------- */
body > header { background: var(--surface); border-bottom: 1px solid var(--line); }
body > header .wrap { display: flex; align-items: center; gap: var(--s-3); min-height: 52px; }
.brand { display: inline-flex; align-items: center; gap: 8px; flex: none; color: var(--ink); font-weight: 700; font-size: 17px; letter-spacing: -0.02em; }
.brand:hover { color: var(--ink); }
.brand svg { width: 22px; height: 22px; flex: none; }
.brand span { color: var(--accent); }
.nav { display: flex; gap: 2px; margin-left: auto; overflow-x: auto; scrollbar-width: none; }
.nav::-webkit-scrollbar { display: none; }
.nav a { display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 10px; border-radius: var(--r-2); color: var(--ink-2); white-space: nowrap; }
.nav a:hover { color: var(--ink); background: var(--surface-2); }
.nav a[aria-current="page"] { color: var(--ink); border-radius: 0; box-shadow: inset 0 -2px 0 var(--accent); }
.nav .lg { display: none; }
@media (min-width: 640px) { .nav { gap: 4px; } .nav .lg { display: inline-flex; } }

/* 4. Ad wells ------------------------------------------------------------ */
/* A well is a labelled, contained band; .slot is the exact-size box the
   network fills. Two sizes are paired in the markup (300×100 mobile /
   728×90 desktop) and only one is ever displayed — fill visible slots only. */
.ad { display: flex; flex-direction: column; align-items: center; gap: var(--s-2); margin: var(--s-6) 0; padding: var(--s-3) var(--s-3) var(--s-4); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-3); }
.ad::before { content: "Advertisement"; font: 500 var(--fs-0)/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.ad .slot { display: grid; place-items: center; width: var(--w, 300px); height: var(--h, 250px); max-width: 100%; background: var(--bg); border: 1px dashed var(--line-2); border-radius: var(--r-1); color: var(--ink-3); font: var(--fs-1) var(--mono); }
.ad[data-size="300x250"] { --w: 300px; --h: 250px; }
.ad[data-size="300x100"] { --w: 300px; --h: 100px; }
.ad[data-size="728x90"]  { --w: 728px; --h: 90px; display: none; }
.ad[data-size="160x600"] { --w: 160px; --h: 600px; }
.ad--top { margin-top: var(--s-4); }
@media (min-width: 768px) {
  .ad[data-size="728x90"] { display: flex; }
  .ad[data-size="300x100"] { display: none; }
}
body > footer .ad { margin: 0; padding: var(--s-4) 0 0; background: transparent; border: 0; border-radius: 0; }

/* 5. Grid + game card ---------------------------------------------------- */
.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-5) var(--s-3); }
@media (min-width: 560px)  { .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-6) var(--s-4); } }
@media (min-width: 900px)  { .grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1500px) { .grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
/* in-grid MREC: spans two cells so it matches card dimensions */
.grid > .ad { grid-column: span 2; margin: 0; padding: var(--s-2); justify-content: center; }

.card { position: relative; display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; color: var(--ink); border-radius: var(--r-2); }
.card:hover { color: var(--ink); }
.card:focus-visible { outline-offset: 4px; }
.cover { position: relative; aspect-ratio: var(--cover-ratio); overflow: hidden; border-radius: var(--r-2); background: var(--surface-2); border: 1px solid var(--line); }
.cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; color: transparent; }
/* Broken-image fallback: pseudo-elements only render on an <img> that failed
   to load, so this paints the title over the striped surface and never a
   browser broken-image glyph. */
.cover img::after { content: attr(alt); position: absolute; inset: 0; display: grid; place-items: center; padding: var(--s-2); text-align: center; color: var(--ink-3); font: var(--fs-1)/1.3 var(--mono); background: var(--surface-2) repeating-linear-gradient(135deg, transparent 0 7px, rgba(255, 255, 255, .03) 7px 8px); }
.card:hover .cover { border-color: var(--line-2); }
.card:hover .title { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--ink-3); }
.card .title { font-size: var(--fs-3); font-weight: 600; line-height: 1.3; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.card .meta { display: flex; align-items: baseline; gap: var(--s-2); min-width: 0; color: var(--ink-3); font-size: var(--fs-1); }
.card .meta .ver { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rating { flex: none; color: var(--ink-2); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.rating::before { content: "★"; color: var(--accent); margin-right: 3px; font-size: .95em; }

/* 6. Updated feed (list variant of the same card) ------------------------ */
.grid--feed { display: flex; flex-direction: column; gap: 0; }
.grid--feed > .card--row { flex-direction: row; align-items: flex-start; gap: var(--s-3); padding: var(--s-3) 0; border-bottom: 1px solid var(--line); border-radius: 0; }
.card--row .cover { flex: none; width: 112px; }
.card--row .body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.change { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; color: var(--ink-3); font-size: var(--fs-1); }
.change .ver { color: var(--ink); font-weight: 600; }
.change .old { color: var(--ink-3); font-weight: 400; }
.change .arr { color: var(--accent); }
.change .rating { margin-left: auto; }
.badge { display: inline-block; padding: 1px 6px; border-radius: var(--r-1); background: var(--accent-soft); color: var(--accent); font: 600 var(--fs-0)/1.6 var(--font); letter-spacing: .04em; text-transform: uppercase; }
.grid--feed > .ad { margin: var(--s-3) 0; }
.day { position: sticky; top: 0; z-index: 1; display: flex; align-items: baseline; gap: var(--s-2); padding: var(--s-5) 0 var(--s-2); background: var(--bg); border-bottom: 1px solid var(--line-2); font-size: var(--fs-3); font-weight: 600; }
.day span { color: var(--ink-3); font-weight: 400; font-size: var(--fs-1); }
@media (min-width: 640px) { .card--row .cover { width: 160px; } .card--row .body { gap: 6px; } }

/* 7. Tags ---------------------------------------------------------------- */
.tags { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.tag { position: relative; display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 0 12px; border: 1px solid var(--line-2); border-radius: var(--r-pill); background: var(--surface); color: var(--ink-2); font-size: var(--fs-2); line-height: 1; white-space: nowrap; }
.tag::before { content: ""; position: absolute; inset: -5px -3px; } /* 44px tap target without visual bulk */
.tag:hover { color: var(--ink); border-color: var(--ink-3); }
.tag .n { color: var(--ink-3); font: var(--fs-0) var(--mono); }
.tag[aria-current="page"] { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.tag[aria-current="page"] .n { color: var(--ink-4); }
.more { display: inline-flex; align-items: center; justify-content: center; min-height: 34px; padding: 0 12px; border: 1px dashed var(--line-2); border-radius: var(--r-pill); background: transparent; color: var(--accent); font-size: var(--fs-2); cursor: pointer; }
.more:hover { border-color: var(--accent); }
.more--block { display: flex; width: 100%; min-height: var(--tap); margin-top: var(--s-2); border-radius: var(--r-3); }
.tags.is-collapsed .tag:nth-child(n + 13) { display: none; }

/* 8. Page head, sections, lede ------------------------------------------ */
.page-head { padding: var(--s-6) 0 var(--s-2); }
.kicker { margin-bottom: var(--s-2); font: 500 var(--fs-0)/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.lede { margin-top: var(--s-3); max-width: 62ch; color: var(--ink-2); font-size: var(--fs-4); }
.stats { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); margin-top: var(--s-3); color: var(--ink-3); font: var(--fs-2) var(--mono); }
.listing h1::first-letter { text-transform: uppercase; }
.listing .grid { margin-top: var(--s-5); }
.sec { margin-top: var(--s-7); }
.sec-head { display: flex; align-items: baseline; gap: var(--s-3); margin-bottom: var(--s-4); }
.sec-head .count { color: var(--ink-3); font: var(--fs-2) var(--mono); }
.sec-head .all { margin-left: auto; color: var(--ink-2); font-size: var(--fs-2); white-space: nowrap; }
.sec-head .all:hover { color: var(--accent); }
.sub { margin: calc(-1 * var(--s-2)) 0 var(--s-4); color: var(--ink-3); font-size: var(--fs-2); max-width: 62ch; }

/* 9. Home — browse entries ---------------------------------------------- */
.browse { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); margin-top: var(--s-5); }
.entry { display: flex; flex-direction: column; justify-content: center; gap: 2px; min-height: 64px; padding: var(--s-3) var(--s-4); border: 1px solid var(--line); border-radius: var(--r-3); background: var(--surface); color: var(--ink); }
.entry:hover { color: var(--ink); background: var(--surface-2); border-color: var(--line-2); }
.entry b { font-weight: 600; }
.entry span { color: var(--ink-3); font: var(--fs-1) var(--mono); }
.entry--hot { grid-column: 1 / -1; border-color: var(--accent); }
.entry--hot b::before { content: ""; display: inline-block; width: 7px; height: 7px; margin-right: 8px; border-radius: 50%; background: var(--accent); vertical-align: 1px; }
@media (min-width: 640px) { .browse { grid-template-columns: repeat(5, minmax(0, 1fr)); } .entry--hot { grid-column: auto; } }

/* 10. Game page ---------------------------------------------------------- */
.hero { display: grid; gap: var(--s-4); }
.hero > .cover { border-radius: var(--r-3); }
.game h1 { font-size: var(--fs-6); }
.by { margin-top: var(--s-2); color: var(--ink-2); font-size: var(--fs-4); }
.by a { color: var(--ink); font-weight: 600; text-decoration: underline; text-decoration-color: var(--line-2); text-underline-offset: 3px; }
.by a:hover { color: var(--accent); text-decoration-color: currentColor; }
.facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3) var(--s-4); margin-top: var(--s-5); padding: var(--s-4); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-3); }
.facts > div { min-width: 0; }
.facts dt { margin-bottom: 2px; font-size: var(--fs-0); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.facts dd { color: var(--ink); overflow-wrap: anywhere; }
.facts dd a { text-decoration: underline; text-decoration-color: var(--line-2); text-underline-offset: 3px; }
.facts .ver { font-size: var(--fs-2); }
.facts .rating { color: var(--ink); font-size: var(--fs-4); }
.facts small { color: var(--ink-3); font-size: var(--fs-1); }
.status::before { content: ""; display: inline-block; width: 7px; height: 7px; margin-right: 6px; border-radius: 50%; background: var(--ink-3); vertical-align: 1px; }
.status--dev::before { background: var(--accent); }
.status--completed::before { background: var(--ok); }
.status--abandoned::before { background: var(--bad); }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: var(--tap); padding: 0 var(--s-4); border: 1px solid var(--line-2); border-radius: var(--r-2); background: var(--surface); color: var(--ink); font-weight: 600; cursor: pointer; }
.btn:hover { color: var(--ink); background: var(--surface-2); border-color: var(--ink-3); }
.btn--primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn--primary:hover { background: #f7c76a; border-color: #f7c76a; color: var(--accent-ink); }
.btn .host { font: var(--fs-1) var(--mono); opacity: .75; }
.btn--out { width: 100%; margin-top: var(--s-4); }
.note { margin-top: var(--s-2); color: var(--ink-3); font-size: var(--fs-1); }

/* screenshots: scroll-snap strip on mobile, grid on desktop */
.strip { display: flex; gap: var(--s-2); margin: 0 calc(-1 * var(--gutter)); padding: 0 var(--gutter) var(--s-2); overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.shot { flex: none; width: min(78vw, 320px); scroll-snap-align: start; }
.shot:hover { border-color: var(--ink-3); }
@media (min-width: 768px) { .strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: 0; padding: 0; overflow: visible; } .shot { width: auto; } }

.versions { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--r-3); overflow: hidden; }
.versions li { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-3) var(--s-4); background: var(--surface); border-top: 1px solid var(--line); }
.versions li:first-child { border-top: 0; }
.versions .ver { flex: 1; min-width: 0; color: var(--ink-2); font-size: var(--fs-2); overflow-wrap: anywhere; }
.versions li:first-child .ver { color: var(--ink); font-weight: 600; }
.versions time { color: var(--ink-3); font-size: var(--fs-1); font-variant-numeric: tabular-nums; white-space: nowrap; }
.versions.is-collapsed li:nth-child(n + 6) { display: none; }

/* lightbox */
dialog.lightbox { width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: transparent; color: var(--ink); }
dialog.lightbox::backdrop { background: rgba(8, 9, 11, .94); }
.lightbox .frame { position: fixed; inset: 0; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; }
.lightbox img { width: 100%; height: 100%; object-fit: contain; }
.lightbox .bar, .lightbox .ctrl { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-3) var(--gutter); color: var(--ink-2); font: var(--fs-2) var(--mono); }
.lightbox .ctrl { justify-content: center; }
.lightbox .bar .close { margin-left: auto; }
.lightbox button { min-width: var(--tap); min-height: var(--tap); padding: 0 var(--s-4); border: 1px solid var(--line-2); border-radius: var(--r-2); background: var(--surface); color: var(--ink); font-size: 18px; cursor: pointer; }
.lightbox button:hover { border-color: var(--ink-3); }

/* 11. Pagination --------------------------------------------------------- */
.pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--s-1); margin: var(--s-7) 0 0; }
.pager a, .pager span { display: inline-flex; align-items: center; justify-content: center; min-width: var(--tap); min-height: var(--tap); padding: 0 var(--s-3); border-radius: var(--r-2); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.pager a:hover { background: var(--surface-2); color: var(--ink); }
.pager a[aria-current="page"] { background: var(--ink); color: var(--bg); font-weight: 600; }
.pager .prev, .pager .next { border: 1px solid var(--line-2); color: var(--ink); font-weight: 600; }
.pager [aria-disabled="true"] { color: var(--ink-4); border-color: var(--line); pointer-events: none; }
.pager .pos { color: var(--ink-3); font-size: var(--fs-2); }
@media (max-width: 559px) { .pager .num, .pager .gap { display: none; } .pager .prev { margin-right: auto; } .pager .next { margin-left: auto; } }
@media (min-width: 560px) { .pager .pos { display: none; } }

/* 12. Footer ------------------------------------------------------------- */
body > footer { margin-top: var(--s-8); padding-bottom: var(--s-7); background: var(--surface); border-top: 1px solid var(--line); }
body > footer .wrap { display: grid; gap: var(--s-4); padding-top: var(--s-6); }
body > footer .brand { justify-self: start; }
.disclaimer { max-width: 60ch; color: var(--ink-3); font-size: var(--fs-2); }
.foot-nav { display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-4); }
.foot-nav a { display: inline-flex; align-items: center; min-height: 32px; color: var(--ink-2); font-size: var(--fs-2); }
.legal { color: var(--ink-3); font: var(--fs-1) var(--mono); }

/* 13. Desktop two-column layout ----------------------------------------- */
.layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-6); }
.layout > * { min-width: 0; }
.rail { display: none; }
@media (min-width: 1024px) {
  .layout { grid-template-columns: minmax(0, 1fr) var(--rail); gap: var(--s-8); align-items: start; }
  .rail { display: flex; flex-direction: column; gap: var(--s-4); padding-top: var(--s-7); }
  .rail .ad { margin: 0; }
  .rail .ad:last-child { position: sticky; top: var(--s-4); }
  .hero { grid-template-columns: minmax(280px, 42%) minmax(0, 1fr); gap: var(--s-6); align-items: start; }
  .game h1 { font-size: var(--fs-7); }
  .facts { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .btn--out { width: auto; }
}

@media (prefers-reduced-motion: no-preference) {
  .card .cover, .tag, .btn, .entry, .nav a { transition: border-color .15s, background-color .15s, color .15s; }
}

/* 14. No-ads mode ---------------------------------------------------------- */
/* When the Worker runs with ADS="0" the rail is not emitted; let the content column
   take the full width instead of leaving an empty 326px rail on desktop. */
.layout > :only-child { grid-column: 1 / -1; }
