/* ==================================================================
   mc.css v3 — SolouMerdeka#26
   Rewritten 2026-08-31 late after Sean: "this looks hideous… it was
   colourful and lively, this looks like shit."

   He was right. v1/v2 kept adding DARK: textured ink topbar, ink
   section heads, ink footer, grey buttons, a big dark rail, muddy
   noise over the cream. The page stopped being cream-with-accents and
   became a wall of grey slabs.

   THE RULE FOR THIS FILE NOW:
     the original scheme is the scheme — cream ground (#f4ecca), flat
     ink furniture, saturated red + gold accents, the red/cream candy
     stripe. mc.css adds Minecraft STRUCTURE (slots, crafting windows,
     pixel type, hearts, the rail) and NEVER repaints the page dark.
     Anything the original styled well is left alone.
   ================================================================== */

@font-face {
  font-family: "Monocraft";
  src: url("assets/fonts/Monocraft.woff2") format("woff2");
  font-weight: 400; font-display: swap;
}
@font-face {
  font-family: "Monocraft";
  src: url("assets/fonts/Monocraft-Bold.woff2") format("woff2");
  font-weight: 700; font-display: swap;
}

:root {
  --rail: 248px;
  /* slots keep the game's geometry, in the site's own warm tones */
  --mc-slot:      #e7dcb4;
  --mc-slot-dark: #b3a67c;
  --mc-slot-lo:   #d3c69c;
  --mc-panel:     #f6f0d8;
  --mc-tip:       rgba(16, 0, 16, .94);
  --mc-tip-edge:  #2d0a63;
  --mc-heart:     #d92b1c;
}
.pixel { image-rendering: pixelated; }

/* the old drawer furniture never renders now */
.menubtn, .scrim, .sb-close { display: none !important; }

/* ---------- pixel type on UI chrome only; prose stays Literata ----------
   #root prefix so these beat the class-on-class rules in styles.css. */
#root :is(.kicker, .stamp, .dircount, .slothead, .craft-head, .sb-label,
.sb-note, .sb-sub, .sb-title, .sb-num, .sb-eyebrow, .stat span, .stat small,
.cap, .e-meta, .e-name, .d-note, .d-num, .tagnote, .sub, .maplegend, .p-chip,
.roster a, .leaflet-control-attribution, .nm, .when, .tag, .topnav a,
.langbtn, .facts .k, .statline .k, .droplist .d-name, .dirfilter button,
.tabbar button, .pill, .p-head h3, .foot-in span, .slot, .gcell,
.dirsearch, .live-pill) {
  font-family: "Monocraft", "IBM Plex Mono", monospace;
}
.sectionhead h2, .mc-title { font-family: "Monocraft", "Silkscreen", monospace; }
#root .kicker { letter-spacing: .16em; }
#root .topnav a { font-size: 12px; letter-spacing: .06em; }

/* ==================================================================
   BACKGROUND — cream, as it always was. Sean's "plain brand colour is
   empty" note is answered with a LIGHT motif, not a dark texture:
   a faint warm grain plus sparse gold-wash studs. Barely there.
   ================================================================== */
/* The depth wash lives in body's own background stack, fixed-attachment.
   It used to be a #root::before overlay, which forced a
   `#root > * { position: relative; z-index: 1 }` rule to lift content back
   above it — and that rule (id specificity) then silently beat the rail's
   `position: fixed` AND the header's `position: sticky`, twice. No overlay,
   no z-index gymnastics, no recurring bug. */
body {
  background-color: var(--cream);
  background-image:
    radial-gradient(120% 70% at 50% 0%, rgba(255, 253, 245, .75), transparent 62%),
    radial-gradient(90% 55% at 50% 100%, rgba(217, 164, 6, .10), transparent 62%),
    url("assets/tex/page.png");
  background-attachment: fixed, fixed, scroll;
  background-size: cover, cover, 288px 288px;
  background-repeat: no-repeat, no-repeat, repeat;
  image-rendering: pixelated;
}
#root { position: relative; }

/* ==================================================================
   THE RAIL - left, collapsible, and sitting UNDER the shared header.
   The topbar spans the full width and the rail starts below it, so the
   page and the rail share one header (Sean, 2026-08-31).
   --topbar-h is measured by app.js and kept fresh on resize.
   ================================================================== */
/* The header must STAY for the rail to stay attached to it: the rail is
   fixed at top:var(--topbar-h), so a header that scrolls away leaves a gap
   above the rail (Sean, 2026-08-31). Sticky header, and the map gets its
   own stacking context so Leaflet's panes can't paint over it. */
.topbar { position: sticky; top: 0; z-index: 80; }
.map-frame { position: relative; z-index: 0; }

@media (min-width: 900px) {
  #root[data-rail="open"] { padding-left: var(--rail); }
  /* the header is shared, so pull it back out over the rail column */
  #root[data-rail="open"] > .topbar { margin-left: calc(-1 * var(--rail)); }
  #root > .sidebar {
    position: fixed; left: 0; right: auto; bottom: 0;
    top: var(--topbar-h, 0px);
    width: var(--rail);
    display: flex; flex-direction: column; overflow-y: auto; z-index: 60;
    /* styles.css still carries the old drawer's translateX(-102%) — this
       id-scoped rule is what puts the open rail back on screen */
    transform: translateX(0);
    transition: transform .22s cubic-bezier(.3, .7, .3, 1);
  }
  #root[data-rail="shut"] > .sidebar { transform: translateX(-100%); }
}

/* narrow: the rail drops in under the header as a two-column block */
@media (max-width: 899px) {
  #root > .sidebar {
    position: relative; z-index: 1; width: auto; transform: none;
    flex-direction: column; overflow: hidden;
    max-height: 60vh; transition: max-height .22s ease, opacity .18s ease;
  }
  #root[data-rail="shut"] > .sidebar {
    max-height: 0; opacity: 0; border-width: 0; pointer-events: none;
  }
  .sidebar .sb-links { display: grid; grid-template-columns: repeat(2, 1fr); }
}

.sidebar {
  background: var(--paper);
  border-right: 4px solid var(--ink);
  border-left: 0;
  color: var(--ink);
}
@media (max-width: 899px) {
  .sidebar { border-right: 0; border-bottom: 4px solid var(--ink); }
}

/* the menu button lives in the shared header */
.menubtn {
  display: inline-flex !important; align-items: center; gap: 9px;
  background: none; border: 2px solid var(--cream); color: var(--cream);
  font-family: "Monocraft", monospace; font-size: 12px; letter-spacing: .1em;
  padding: 7px 11px; cursor: pointer; text-transform: uppercase;
}
.menubtn:hover { background: var(--red); border-color: var(--red); }
.menubtn .bars { display: grid; gap: 3px; }
.menubtn .bars i { display: block; width: 15px; height: 2px; background: currentColor; }
@media (max-width: 620px) { .menubtn span[lang] { display: none; } }

/* rail items: cream cards, each a clearly separate block */
.sb-links { padding: 8px; display: grid; gap: 8px; }
.sb-links a {
  display: grid; grid-template-columns: 26px 1fr; gap: 10px; align-items: start;
  padding: 11px 11px 11px 9px;
  background: var(--cream-lt);
  border: 2px solid var(--rule);
  border-left: 6px solid var(--rule);
  text-decoration: none; color: var(--ink);
}
.sb-num { font-size: 12px; color: var(--ink-faint); padding-top: 3px; }
.sb-title { display: block; font-size: 14px; letter-spacing: .06em; line-height: 1.25; }
.sb-links a .sb-sub {
  display: block; margin-top: 4px; font-size: 10.5px; line-height: 1.5;
  color: var(--ink-soft);
}
.sb-links a:hover {
  background: var(--gold-wash); border-color: var(--flag-gold);
  border-left-color: var(--flag-gold);
}
.sb-links a[aria-current="page"] {
  background: var(--red); border-color: var(--ink); border-left-color: var(--flag-gold);
  color: var(--cream); box-shadow: 3px 3px 0 var(--rule);
}
.sb-links a[aria-current="page"] .sb-num { color: var(--flag-gold); }
.sb-links a[aria-current="page"] .sb-sub { color: #eadfc0; }

.sb-foot { margin-top: auto; padding: 12px; border-top: 2px solid var(--rule); }
.sb-label {
  font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-faint); margin: 0 0 8px;
}
.sb-foot .langset { display: flex; width: 100%; border: 0; background: none; gap: 8px; }
.sb-foot .langbtn { flex: 1; color: var(--ink); }
.sb-foot .langbtn[aria-pressed="true"] { color: var(--cream); }
.sb-note { margin: 12px 0 0; font-size: 11px; color: var(--ink-faint); }

/* ==================================================================
   BUTTONS — light and punchy. Pixel geometry (square, hard shadow),
   brand colour, gold hover, red for the selected state.
   ================================================================== */
.tabbar button, .dirfilter button, .langbtn, .live-pill, button.btn {
  background: var(--paper); color: var(--ink);
  border: 2px solid var(--ink); border-radius: 0;
  box-shadow: 3px 3px 0 var(--rule);
  padding: 10px 15px; cursor: pointer; text-shadow: none;
  transition: background .1s, box-shadow .1s, transform .1s;
}
.tabbar button:hover, .dirfilter button:hover, .langbtn:hover,
.live-pill:hover, button.btn:hover {
  background: var(--gold-wash); box-shadow: 3px 3px 0 var(--flag-gold);
  color: var(--ink);
}
.tabbar button:active, .dirfilter button:active, .live-pill:active {
  transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--rule);
}
.tabbar button[aria-selected="true"], .dirfilter button[aria-pressed="true"],
.langbtn[aria-pressed="true"], .sb-foot .langbtn[aria-pressed="true"] {
  background: var(--red); color: var(--cream); border-color: var(--ink);
  box-shadow: 3px 3px 0 var(--flag-gold);
}
.tabbar { gap: 8px; flex-wrap: wrap; }
.tabbar button + button, .dirfilter button + button { border-left: 2px solid var(--ink); }
.dirfilter { gap: 6px; }
.tabbar .n { opacity: .65; margin-left: 6px; }

/* the index live-bar: three colour-coded entry points, not grey slabs */
.livebar { gap: 12px; }
.livebar .live-pill {
  font-size: 13.5px; display: inline-flex; align-items: center; gap: 10px;
  text-decoration: none;
}
.livebar .live-pill:nth-child(1) { border-left: 6px solid var(--grass-deep); }
.livebar .live-pill:nth-child(2) { border-left: 6px solid var(--sky); }
.livebar .live-pill:nth-child(3) { border-left: 6px solid var(--flag-gold); }
.livebar .live-pill b { font-weight: 400; color: var(--red); }
.livebar .live-pill .dot { background: var(--grass-deep); }

/* search field: paper, not a black box */
.dirsearch {
  background: var(--paper); color: var(--ink);
  border: 2px solid var(--ink); border-radius: 0;
  box-shadow: 3px 3px 0 var(--rule);
  padding: 11px 13px; font-size: 15px;
}
.dirsearch:focus { outline: none; box-shadow: 3px 3px 0 var(--flag-gold); }
.dirsearch::placeholder { color: var(--ink-faint); }

/* ==================================================================
   SLOTS + CRAFTING WINDOW — the Minecraft bit that actually worked.
   Warm sand instead of vanilla grey so it belongs on a cream page.
   ================================================================== */
.slot, .gcell {
  width: 62px; height: 62px; padding: 4px; border: 0; border-radius: 0;
  background: var(--mc-slot);
  box-shadow: inset 3px 3px 0 var(--mc-slot-dark), inset -3px -3px 0 #fffdf5;
  font-size: 10px; line-height: 1.15; color: var(--ink);
  display: grid; place-items: center; text-align: center;
  position: relative; overflow: visible;
}
.slot[data-filled], .gcell:not(.empty) {
  background: var(--mc-slot); color: var(--ink);
  box-shadow: inset 3px 3px 0 var(--mc-slot-dark), inset -3px -3px 0 #fffdf5;
}
.slot:not([data-filled]), .gcell.empty {
  background: var(--mc-slot-lo);
  box-shadow: inset 3px 3px 0 #b0a377, inset -3px -3px 0 #eee5c4;
}
.slot[data-filled]:hover::after, .gcell:not(.empty):hover::after {
  content: ""; position: absolute; inset: 3px;
  background: rgba(255, 255, 255, .55); pointer-events: none;
}
.slot[data-sel] { outline: 3px solid var(--flag-gold); outline-offset: 2px; }
.slot .cnt {
  position: absolute; right: 4px; bottom: 4px; font-size: 12px; line-height: 1;
  color: var(--ink); font-weight: 700;
}
.slot .ench, .gcell .ench { color: #7a3fd4; font-size: 10px; top: 3px; left: 5px; }
.gcell.tagcell {
  background: var(--navy-wash); color: var(--navy);
  box-shadow: inset 3px 3px 0 #aab6d8, inset -3px -3px 0 #fbfcff;
}
.outcell, .gcell.outcell {
  background: var(--mc-slot);
  box-shadow: inset 3px 3px 0 var(--mc-slot-dark), inset -3px -3px 0 #fffdf5,
              0 0 0 3px var(--ink);
}
.arrow { font-size: 0; width: 32px; height: 20px; position: relative; flex: 0 0 auto; }
.arrow::before {
  content: ""; position: absolute; left: 0; top: 7px; width: 20px; height: 6px;
  background: var(--red);
}
.arrow::after {
  content: ""; position: absolute; right: 0; top: 2px;
  border: 8px solid transparent; border-left: 12px solid var(--red); border-right: 0;
}
.craftway {
  background: var(--mc-panel);
  border: 2px solid var(--rule); border-left: 6px solid var(--flag-gold);
  padding: 14px 16px 16px; margin-bottom: 14px;
}
.craftway + .craftway { border-top: 2px solid var(--rule); padding-top: 14px; }
.craftrow { gap: 18px; }
.grid { gap: 5px; }
.slotrow { gap: 6px; }

/* item tooltip — the one place the game's dark panel belongs */
.mc-tip {
  position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%);
  min-width: 130px; max-width: 220px; z-index: 40; text-align: left;
  background: var(--mc-tip); color: #fff;
  border: 2px solid var(--mc-tip-edge);
  padding: 7px 9px; pointer-events: none; opacity: 0; transition: opacity .09s;
  font-family: "Monocraft", monospace; font-size: 12.5px; line-height: 1.5;
  white-space: normal; text-shadow: 2px 2px 0 rgba(0, 0, 0, .8);
}
.slot:hover .mc-tip, .slot:focus .mc-tip,
.gcell:hover .mc-tip, .gcell:focus .mc-tip { opacity: 1; }
.mc-tip .t-name { color: #fff; }
.mc-tip .t-ench { color: #a8a8ff; }
.mc-tip .t-sub  { color: #aaa; }

/* pixel hearts */
.hearts { display: inline-flex; gap: 3px; vertical-align: -1px; }
.mc-heart {
  width: 15px; height: 13px; position: relative; display: inline-block;
  filter: drop-shadow(2px 2px 0 rgba(44, 45, 50, .28));
}
.mc-heart i {
  position: absolute; inset: 0; background: var(--mc-heart);
  clip-path: polygon(
    12.5% 0,   37.5% 0,    37.5% 14%,  62.5% 14%,  62.5% 0,
    87.5% 0,   87.5% 14%,  100% 14%,   100% 57%,   87.5% 57%,
    87.5% 71%, 75% 71%,    75% 85%,    62.5% 85%,  62.5% 100%,
    37.5% 100%, 37.5% 85%, 25% 85%,    25% 71%,    12.5% 71%,
    12.5% 57%, 0 57%,      0 14%,      12.5% 14%);
}
.mc-heart::before {
  content: ""; position: absolute; left: 12.5%; top: 14%;
  width: 25%; height: 22%; background: #ff6a5c; z-index: 1;
}
.hearts .more { color: var(--mc-heart); margin-left: 2px; }

/* cards: paper with a hard pixel shadow — light, with a colour edge */
.entry {
  background: var(--paper); border: 2px solid var(--rule); border-radius: 0;
  box-shadow: 4px 4px 0 rgba(222, 211, 171, .55); margin-bottom: 12px;
}
.entry[open] { border-color: var(--ink); box-shadow: 5px 5px 0 var(--rule); }
.entry[open] > summary { border-bottom: 2px solid var(--rule); background: var(--cream-lt); }
.entry .e-name { font-size: 16px; }
.stat {
  background: var(--paper); border: 2px solid var(--rule); border-top: 4px solid var(--flag-gold);
  box-shadow: 3px 3px 0 rgba(222, 211, 171, .5);
}
.stat b { color: var(--ink); }
.droplist .d-pct {
  background: var(--grass-deep); color: #eaffd9; border: 0;
  box-shadow: 2px 2px 0 var(--rule); padding: 2px 7px; font-weight: 600;
}
.pill { border-width: 2px; }
.map-frame, .viewer-card {
  border: 2px solid var(--ink); border-radius: 0;
  box-shadow: 5px 5px 0 var(--rule); background: var(--paper); padding: 6px;
}
.roster a, .p-chip { border-radius: 0; }
.roster a[aria-current="true"] {
  border-color: var(--ink); background: var(--gold-wash); box-shadow: 3px 3px 0 var(--flag-gold);
}

/* ==================================================================
   PIXEL TYPE EVERYWHERE — Sean, 2026-08-31: "lots of different text is
   missing the pixel font."

   This supersedes the earlier "no pixel font under 16px" ruling from
   the onboarding page: Monocraft is now the face for ALL Latin text,
   with the body size lifted to 16px and the line-height opened up so
   it stays readable at length.

   TWO EXCEPTIONS, both deliberate:
     1. Chinese — there is no pixel CJK face, so 中文 stays Noto Sans SC.
        Monocraft has no CJK glyphs; forcing it would render tofu.
     2. The SOLOU wordmark keeps Silkscreen, which is the logo face.
   `#root *` (1,0,0) is what beats the per-element Literata rules in
   styles.css, e.g. `.sectionhead .kicker` (0,2,0).
   ================================================================== */
#root, #root * {
  font-family: "Monocraft", "IBM Plex Mono", monospace;
}
#root[data-lang="zh"], #root[data-lang="zh"] * {
  font-family: "Noto Sans SC", sans-serif;
}
#root .wordmark, #root[data-lang="zh"] .wordmark {
  font-family: "Silkscreen", monospace;
}
#root :is(.mc-tip, .mc-tip *) { font-family: "Monocraft", monospace; }

/* monospace runs wider and reads heavier — give it room */
body { font-size: 16px; line-height: 1.72; }
#root :is(p, dd, li, .blurb, .lede) { line-height: 1.75; }
#root { --measure: 54ch; }
#root :is(h1, h2, h3) { line-height: 1.2; letter-spacing: .01em; }
#root .blurb { font-size: 15.5px; }
#root .disclaimer { font-size: 11.5px; line-height: 1.6; }
#root strong, #root b { font-weight: 700; }
/* Literata's italics carried the emphasis; Monocraft has none worth using */
#root :is(em, i, .d-note) { font-style: normal; color: var(--ink-soft); }
#root .d-note { color: var(--ink-faint); }

/* ==================================================================
   The candy stripe is gone (Sean, 2026-08-31).
   ================================================================== */
.stripe { display: none !important; }
footer { margin-top: 48px; border-top: 4px solid var(--flag-gold); }

/* ==================================================================
   PRESS FEEDBACK — everything clickable lifts on hover and physically
   sinks on press, the way a Minecraft button does. The shadow is the
   trick: it shrinks as the element moves into it, so the travel reads.
   ================================================================== */
#root :is(.tabbar button, .dirfilter button, .langbtn, .live-pill,
button.btn, .sb-links a, .roster a, .p-chip, .entry > summary, .slot, .gcell) {
  transition: transform .09s ease-out, box-shadow .09s ease-out,
              background-color .12s ease, border-color .12s ease;
}
#root :is(.tabbar button, .dirfilter button, .langbtn, .live-pill,
button.btn, .roster a, .p-chip):hover {
  transform: translate(-1px, -1px);
  box-shadow: 4px 4px 0 var(--flag-gold);
}
#root :is(.tabbar button, .dirfilter button, .langbtn, .live-pill,
button.btn, .roster a, .p-chip):active {
  transform: translate(3px, 3px);
  box-shadow: 0 0 0 var(--rule);
}
#root .sb-links a:hover { transform: translateX(3px); }
#root .sb-links a:active { transform: translateX(3px) scale(.985); }
#root .entry > summary:active { transform: translateX(2px); }

/* The pop is driven by app.js adding .mc-pressed to the element the user
   actually clicked - NOT by [aria-selected]/[aria-pressed], which re-apply
   every time a list re-renders and so made every selectable control fire at
   once (Sean, 2026-08-31). Tie feedback to the EVENT, never to the STATE. */
@keyframes mc-pop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.06); }
  100% { transform: scale(1); }
}
#root .mc-pressed { animation: mc-pop .19s ease-out; }

/* slots: lift under the cursor, punch in on click */
#root :is(.slot, .gcell):not(.empty):hover { transform: translateY(-2px); }
#root :is(.slot, .gcell):not(.empty):active { transform: translateY(1px) scale(.97); }

/* checklist ticks get a satisfying snap */
@keyframes mc-tick { 0% { transform: scale(.6) rotate(-12deg); } 100% { transform: scale(1); } }
#root .tick input:checked { animation: mc-tick .22s cubic-bezier(.2, 1.5, .4, 1); }
#root .step[data-done] { transition: opacity .2s ease; }

/* keyboard users get the same affordance */
#root :is(button, a, input, summary):focus-visible {
  outline: 3px solid var(--flag-gold); outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  #root *, #root *::before, #root *::after {
    animation: none !important; transition: none !important;
  }
  #root :is(button, a, summary):hover,
  #root :is(button, a, summary):active { transform: none !important; }
}

/* ==================================================================
   ITEM ICONS — Pixel Perfection CE, CC BY-SA 4.0 (credit in the footer
   and in assets/icons/CREDIT.txt). No Mojang game files are used.
   ================================================================== */
.ico {
  image-rendering: pixelated;
  width: 32px; height: 32px; display: block; flex: 0 0 auto;
}
.gcell.has-ico, .slot.has-ico { gap: 2px; }
.gcell.has-ico .lbl, .slot.has-ico .lbl {
  font-size: 8.5px; line-height: 1.1; max-height: 20px; overflow: hidden;
  color: var(--ink-soft);
}
.gcell.has-ico .ico, .slot.has-ico .ico { width: 30px; height: 30px; }
.p-chip .ico { width: 18px; height: 18px; display: inline-block; vertical-align: -4px; margin-right: 3px; }
.ico-head { width: 26px; height: 26px; margin-right: 2px; }
#root .entry > summary { align-items: center; }
.droplist li .ico { width: 22px; height: 22px; }

/* the numbers strip on an item card */
.istats {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px; margin: 8px 0 14px;
}
.istat {
  background: var(--cream-lt); border: 2px solid var(--rule);
  border-left: 5px solid var(--flag-gold); padding: 7px 10px;
}
.istat .k {
  display: block; font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint); margin-bottom: 2px;
}
.istat b { font-size: 14px; line-height: 1.25; display: block; }
.istat b small { font-size: 10.5px; color: var(--ink-faint); }
