/* RetroBox — shared styles.
   Visual language: cartridge label printing. Flat label stock, heavy ink,
   a colour band per platform that encodes which system you're looking at. */

/* ---------------------------------------------------------------------------
   Themes.

   Every colour in the app resolves through these variables, so a theme is just
   an override block — no per-component styling. Add one by copying a block and
   adding the key to GLOBAL_SCHEMA.theme in src/settings.js.

   --page-image is empty by default. Point it at a url() to drop a background
   photo behind everything; --page-veil controls how much is scrimmed back so
   text stays readable.
--------------------------------------------------------------------------- */

:root{
  --plastic:#c9c3b4;
  --plastic-dk:#b3ac9b;
  --label:#f2efe6;
  --ink:#1c1a17;
  --ink-soft:#5c564c;
  --hair:rgba(28,26,23,.18);

  --nintendo:#a32b22;
  --sega:#2c5d8f;
  --sony:#3f3f44;
  --handheld:#5c7a3f;
  --arcade:#c4922b;
  --other:#7a5a8c;

  --ochre:#c4922b;
  --red:#a32b22;

  /* Backdrop behind console photos. Product shots almost always come on a
     white background, so matching it means the photo sits in a frame rather
     than floating as a brighter rectangle inside the tile. */
  --art-bg:#ffffff;

  --page-image:none;
  --page-veil:rgba(0,0,0,0);
  --texture:repeating-linear-gradient(90deg,rgba(0,0,0,.016) 0 1px,transparent 1px 3px);
}

/* Midnight — dark, for playing at night without a wall of light. */
[data-theme="midnight"]{
  --plastic:#1b1d21;
  --plastic-dk:#101114;
  --label:#262a30;
  --ink:#e8e4da;
  --ink-soft:#9a9488;
  --hair:rgba(232,228,218,.16);

  --nintendo:#e0564a;
  --sega:#5a9bd8;
  --sony:#a9a9b4;
  --handheld:#8fbf5f;
  --arcade:#e3b552;
  --other:#b48ac9;

  --ochre:#e3b552;
  --red:#e0564a;
  --texture:none;
  /* Not pure white in the dark theme — a photo frame should read as paper,
     not as a lightbulb. */
  --art-bg:#d9d5c9;
}

/* Paper — high contrast, flat, closest to a printed catalogue page. */
[data-theme="paper"]{
  --plastic:#e8e4d9;
  --plastic-dk:#cdc7b8;
  --label:#fdfcf8;
  --ink:#14120f;
  --ink-soft:#6b655a;
  --texture:none;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--plastic);
  color:var(--ink);
  font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  font-size:16px;line-height:1.45;
  background-image:var(--texture);
}

/* Background photo layer. Sits behind everything, fixed so it doesn't scroll
   away, with a veil over it so label cards stay legible. */
body::before{
  content:"";position:fixed;inset:0;z-index:-2;
  background-image:var(--page-image);
  background-size:cover;background-position:center;
  }
body::after{
  content:"";position:fixed;inset:0;z-index:-1;
  background:var(--page-veil);
}
a{color:inherit}
.wrap{max-width:1180px;margin:0 auto;padding:20px 18px 64px}

/* ---- masthead -------------------------------------------------------- */
.top{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding-bottom:14px;margin-bottom:18px;
  border-bottom:2px solid var(--ink);
}
.brand{
  font-size:clamp(22px,5vw,32px);font-weight:800;letter-spacing:-.03em;
  text-decoration:none;margin:0;
}
.crumb{font-size:14px;color:var(--ink-soft)}
.spacer{margin-left:auto}

.btn{
  font:inherit;font-size:13px;font-weight:650;
  padding:5px 11px;
  color:var(--ink);background:var(--label);
  border:1.5px solid var(--ink);border-radius:2px;
  cursor:pointer;text-decoration:none;display:inline-block;
}
.btn:active{transform:translate(1px,1px)}
.btn:disabled{opacity:.55;cursor:default;transform:none}
.btn.solid{background:var(--ink);color:var(--label)}
.btn.wide{width:100%;padding:11px;font-size:15px;font-weight:750}
:focus-visible{outline:3px solid var(--ochre);outline-offset:2px}

/* ---- search ---------------------------------------------------------- */
.search{
  width:100%;padding:11px 14px;margin-bottom:16px;
  font:inherit;font-size:16px;      /* 16px keeps iOS from zooming on focus */
  color:var(--ink);background:var(--label);
  border:1.5px solid var(--ink);border-radius:2px;
}
.search::placeholder{color:var(--ink-soft)}

/* ---- grids ----------------------------------------------------------- */
.grid{display:grid;gap:14px}
.grid.consoles{grid-template-columns:repeat(auto-fill,minmax(176px,1fr))}
.grid.games{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}

/* ---- the label card -------------------------------------------------- */
.cart{
  position:relative;display:flex;flex-direction:column;
  padding:11px 11px 9px 18px;
  background:var(--label);color:inherit;text-decoration:none;
  border:1.5px solid var(--ink);border-radius:2px 4px 4px 2px;
  box-shadow:2px 2px 0 var(--plastic-dk);
  transition:transform .08s ease,box-shadow .08s ease;
}
.cart::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:7px;
  background:var(--band,var(--other));border-right:1.5px solid var(--ink);
}
.cart:active{transform:translate(2px,2px);box-shadow:0 0 0 var(--plastic-dk)}

.cart .kicker{font-size:11px;font-weight:700;color:var(--band,var(--other));margin-bottom:5px}
.cart .name{font-size:16px;font-weight:750;line-height:1.2;letter-spacing:-.02em;margin:0 0 auto;overflow-wrap:anywhere}
.cart .meta{
  margin-top:9px;padding-top:6px;border-top:1px solid var(--hair);
  font-size:11px;color:var(--ink-soft);font-variant-numeric:tabular-nums;
  display:flex;justify-content:space-between;gap:8px;
}

/* Cover art. object-fit:contain because box art aspect ratios vary wildly
   between systems and cropping loses the title. */
.cart .art{
  width:100%;aspect-ratio:1/1;margin-bottom:8px;
  object-fit:contain;background:#e6e1d5;
  border:1px solid var(--ink);
}
.cart .art.pixel{image-rendering:pixelated}
.cart .art.blank{
  /* Flat, not hatched: several of these land next to each other whenever a
     system's art coverage is patchy, and a pattern turns that into noise. */
  background:var(--plastic-dk);
  opacity:.5;
}

/* ---- console tiles ----------------------------------------------------
   A stack of boxes with the cartridge label across the bottom: real art from
   that system fills the tile, the name sits on opaque label stock so it stays
   readable over whatever the covers happen to be, and the system band runs the
   full height down the left. A console with no art falls back to the plain
   label, which is why .plate carries its own padding rather than relying on
   the mosaic being there. */
.grid.consoles .cart{
  padding:0;overflow:hidden;justify-content:flex-end;min-height:84px;
}
.grid.consoles .cart::before{width:9px;z-index:2}

.mosaic{
  display:grid;
  grid-template-columns:1fr 1fr;
  /* Explicit rows + min-height:0 are both load-bearing. Without them the rows
     auto-size to the images' own height and aspect-ratio is ignored, so the
     tile grows to whatever shape the box art happens to be — and box art is
     portrait, so tiles end up enormous. */
  grid-template-rows:1fr 1fr;
  min-height:0;
  gap:1px;background:var(--ink);
  margin-left:9px;aspect-ratio:4/3;
}
.mosaic img{
  width:100%;height:100%;min-height:0;display:block;
  /* Box art is portrait and its logo sits up top, so bias the crop upward —
     a centred crop on a landscape cell throws away exactly the part that makes
     a cover recognisable. */
  object-fit:cover;object-position:center 28%;
  background:#ded8ca;
}
/* One or two covers shouldn't leave holes in a 2x2 grid. */
.mosaic.one{grid-template-columns:1fr;grid-template-rows:1fr}
.mosaic.two{grid-template-rows:1fr;aspect-ratio:8/3}

/* Console photo. Product shots arrive at every aspect ratio and usually on a
   white backdrop, so contain-and-letterbox against label stock rather than
   cropping — it reads as a printed catalogue entry instead of a bad crop. */
.conart{
  margin-left:9px;aspect-ratio:4/3;
  background:var(--art-bg);
  display:flex;align-items:center;justify-content:center;
  padding:4px;min-height:0;
}
.conart img{
  max-width:100%;max-height:100%;
  width:auto;height:auto;display:block;
  object-fit:contain;
}

.plate{
  padding:9px 11px 8px 20px;
  background:var(--label);
  border-top:1.5px solid var(--ink);
  /* Reserve two lines of title. "Game Boy Advance" wraps and "NES" doesn't,
     and without this the tiles in a row end at different heights. Centring
     keeps the one-line names from sitting against the top of the reserved box. */
  min-height:80px;
  display:flex;flex-direction:column;justify-content:center;
}
.mosaic + .plate,
.conart + .plate{border-top:1.5px solid var(--ink)}
/* No art for this system yet: let the label fill the tile and centre the name,
   rather than leaving a tall empty box where the mosaic would have gone. */
.cart:not(:has(.mosaic)):not(:has(.conart)) .plate{
  border-top:0;flex:1;justify-content:center;padding:16px 12px 15px 20px;
}

.grid.consoles .name{font-size:18px;margin:0 0 2px}
.grid.consoles .meta{margin:0;padding:0;border:0}

/* Phones: a shorter mosaic so more than two consoles fit on screen. */
@media (max-width:540px){
  .mosaic,.conart{aspect-ratio:16/9}
}

/* ---- horizontal strip (recently played) ------------------------------ */
.strip{
  display:grid;grid-auto-flow:column;grid-auto-columns:minmax(148px,1fr);
  gap:12px;overflow-x:auto;padding:2px 2px 10px;
  scroll-snap-type:x proximity;
}
.strip .cart{scroll-snap-align:start}
.section-head{
  display:flex;align-items:baseline;gap:10px;
  margin:0 0 10px;font-size:13px;font-weight:750;
  text-transform:none;color:var(--ink-soft);
}

/* ---- forms ----------------------------------------------------------- */
.panel{
  background:var(--label);border:1.5px solid var(--ink);border-radius:2px;
  padding:18px 18px 16px;margin-bottom:16px;
  box-shadow:2px 2px 0 var(--plastic-dk);
}
.panel h2{margin:0 0 3px;font-size:18px;font-weight:800;letter-spacing:-.02em}
.panel .hint{margin:0 0 16px;font-size:13px;color:var(--ink-soft)}

.field{display:flex;align-items:center;gap:14px;padding:9px 0;border-top:1px solid var(--hair)}
.field:first-of-type{border-top:0}
.field label{flex:1;font-size:14px;font-weight:650}
.field .sub{display:block;font-weight:400;font-size:12px;color:var(--ink-soft);margin-top:1px}
.field select,.field input[type=range]{flex:0 0 172px}
select{
  font:inherit;font-size:14px;padding:6px 8px;
  background:#fff;color:var(--ink);
  border:1.5px solid var(--ink);border-radius:2px;
}
input[type=range]{accent-color:var(--red)}
input[type=checkbox]{width:19px;height:19px;accent-color:var(--red)}

.notice{
  padding:9px 11px;margin-bottom:14px;font-size:13px;border-radius:2px;
  color:var(--label);background:var(--ink);
}
.notice.bad{background:var(--red)}
.notice[hidden]{display:none}

.empty{
  grid-column:1/-1;padding:30px 20px;
  border:2px dashed var(--ink);border-radius:2px;
}
.empty p{margin:0 0 7px;font-size:17px;font-weight:650}
code{background:var(--label);padding:1px 5px;border:1px solid var(--ink);font-size:13px}

@media (prefers-reduced-motion:reduce){*{transition:none!important}}
