/* Pixel UI (since 2026-10-30, the only look since 11-01; user: "도트 텍스트화 … ui 디자인"): a pixel font
   and pixel boxes so the UI matches the pixel art. Everything here sits under html.px (set in index.html), over the
   plain look in style.css.
   One UI pixel is 2 CSS px (--p). Boxes keep their 2 px border but lose the corner pixel (clip-path), the way pixel
   art rounds a corner; buttons get a lighter top row and a darker bottom row inside, and sink a pixel when pressed.
   Font: Fusion Pixel 12px proportional (SIL OFL 1.1, assets/font/OFL.txt and LICENSES/ — the fonts it is built from;
   cut to Latin and the symbols the UI uses — 2026-10-31, user chose it over Pixelify Sans, which smudged at small
   sizes: "폰트가 너무 가독성 떨어져" → "fusion pixel"). Drawn on a 12-pixel grid, so sizes are 12 / 16 / 20 / 24: whole
   screen pixels per font pixel on a 3x phone (and 12 / 24 on a 2x one); nothing smaller than 12. */
@font-face { font-family: "Fusion Pixel"; src: url("assets/font/FusionPixel12.woff2") format("woff2"); font-display: swap; }

.px {
  --p: 2px;
  --o: #d79bb4;            /* box outline */
  --o-strong: #c25a82;     /* outline of the main buttons */
  --accent-lo: #e8578a;    /* bottom row inside the main buttons */
  --accent-hi: #ffa3c0;    /* top row inside the main buttons */
  --card-lo: #f6dce6;      /* bottom row inside light boxes */
  --corner: polygon(var(--p) 0, calc(100% - var(--p)) 0, calc(100% - var(--p)) var(--p), 100% var(--p), 100% calc(100% - var(--p)),
    calc(100% - var(--p)) calc(100% - var(--p)), calc(100% - var(--p)) 100%, var(--p) 100%, var(--p) calc(100% - var(--p)),
    0 calc(100% - var(--p)), 0 var(--p), var(--p) var(--p));
}
/* One weight in the font: a browser's made-up bold smears it, so it is off, and the bold that is wanted is a pixel bold
   — the text again one font pixel to the right (1/12 em: a whole number of screen pixels on a 3x phone at these sizes).
   Sizes (user: "폰트사이즈 너무 큰거나 그런거 적당히 맞추고, 너무얇은 폰트웨이트는 좀 키워야"): 20 a big title, 16 what
   you read and the main buttons, 12 small buttons, labels and small print; titles, names and every button in pixel
   bold, small print a shade darker than before so it doesn't look faint. */
html.px, .px body { font: 16px/1.45 "Fusion Pixel", ui-rounded, system-ui, sans-serif; -webkit-font-smoothing: none; font-synthesis: none;
  text-shadow: var(--medium); }
/* plain text a little heavier, not bold: the text again a pixel to the right at half strength — no wider, no letters run
   together (10-31, user: "아래 탭바 글씨가 조금 얇다 같은 weight인 다른 텍스트들도 그렇고") */
.px { --medium: 1px 0 0 color-mix(in srgb, currentColor 70%, transparent); }   /* 50% was still thin (user: "아직도 좀 얇다"); under bold's 100% */
.px * { font-weight: 400 !important; }
.px { --muted: #86687a; }
.px :is(b, strong, h2, h3, button, .top, .chip, .gameCard b, .bookRow b, .whoChip b, .guide b, .careBar, .coins) {
  text-shadow: 1px 0 0 currentColor;
  letter-spacing: 1px; }   /* the pixel the bold adds to each letter, given back as space: bold letters ran together (10-31, user: "letter spacing … 약간 넓혀도"); 1px, not a font pixel — at 16–20 px that was too heavy (user: "bold 너무 두꺼운건 좀 줄여야") */
.px :is(b, strong) { color: var(--ink); }
.px button, .px input, .px select { font-family: inherit; }
.px h2 { font-size: 20px; }
.px h3 { font-size: 12px; letter-spacing: .08em; color: var(--muted); }
.px .top, .px .coins b { font-size: 16px; }
.px :is(.pill, .big, .careBar, .banner, .gameCard b, .bookRow b, .list li b, .modal p) { font-size: 16px; }
.px :is(.pill.small, .chip, .tile) { font-size: 12px; }
.px :is(small, .fine, .muted, .bondRow, .guestbook, .status, .doc p, .guide small, .whoChip small, .swatch span, .thumb small,
  .tray .tile div, .tray .tile small, .reveal small, .gameCard small) { font-size: 12px; }
.px .whoChip b { font-size: 12px; color: var(--ink); }
/* small print stays plain (medium), even inside a button — the bold and its spacing are inherited */
.px :is(small, .fine, .muted, .bondRow, .guestbook, .status, .gameCard small, .whoChip small, .swatch span, .thumb small, .reveal small, .guide small) {
  text-shadow: var(--medium); letter-spacing: normal; }

/* pixel boxes */
.px :is(.pill, .big, .tab, .tile, .panel, .card, .hudTop, .moreMenu, .dock, .roomDock, .gameCard, .bookRow, .list li, .friend, .guide, .say, .banner, .stamp, .chip,
  input, select, .linkInput, fieldset.choices, .toast, .scene, .portrait, .hudBottom .guestbook, .hudBottom .link) {
  border-radius: 0;
  clip-path: var(--corner);
}
.px :is(.pill, .tab, .tile, .panel, .hudTop, .moreMenu, .dock, .roomDock, .gameCard, .bookRow, .list li, .friend, .stamp, .chip, input, select, .linkInput,
  fieldset.choices, .say) { border-color: var(--o); }
.px .linkInput input { clip-path: none; }
.px :is(.thumb small, .tray .tile small.n, .swatch small) { border-radius: 0; clip-path: var(--corner); padding: 0 2px 1px 4px; }   /* the font's glyphs sit a pixel low and left */
.px :is(.pill, .tab) { box-shadow: inset 0 calc(-1 * var(--p)) 0 var(--card-lo); }
.px :is(.pill.accent, .big) { border: var(--p) solid var(--o-strong); box-shadow: inset 0 var(--p) 0 var(--accent-hi), inset 0 calc(-2 * var(--p)) 0 var(--accent-lo); }
.px .big { padding: 12px 14px 14px; font-size: 16px; }
.px :is(.pill, .big, .tab, .gameCard, .tile, .guide):active:not(:disabled) { transform: translateY(var(--p)); box-shadow: none; }
.px .pill.danger { border-color: #e8a0a0; }
.px .tab.on { border-color: var(--accent); background: #fff0f5; }
.px .tile.on, .px .list li.me { border-color: var(--accent); }
.px .hudTop, .px .dock, .px .roomDock { background: #fff8fbf2; box-shadow: inset 0 calc(-1 * var(--p)) 0 var(--card-lo); }
.px .dockFace img { border-radius: 0; border: var(--p) solid var(--o); clip-path: var(--corner); }
.px .dockHead .bar { height: 12px; }
.px .card { border: var(--p) solid var(--o-strong); }
.px .card.ad { border-color: #555; }
.px .toast { border: var(--p) solid #2d1c27; background: #4a2f3f; }
.px .guide { border-color: var(--accent); box-shadow: none; }
.px .gameCard.today { border-color: #e0b24a; }
.px .bookRow.full { border-color: #e0b24a; }
.px .sceneBtn, .px .floatBtn { box-shadow: inset 0 calc(-1 * var(--p)) 0 var(--card-lo); }
.px .gameCanvas { box-shadow: none; }   /* edge to edge (stage.js fitPlay): no frame round it */
.px :is(.gameResult, .gameIntro) { border-radius: 0; border: var(--p) solid var(--o); clip-path: var(--corner); }
.px .gameSay { border-radius: 0; border: var(--p) solid var(--o); clip-path: var(--corner); }
.px .scene, .px .portrait { border: var(--p) solid var(--o); }
.px .cert { border-radius: 0; box-shadow: none; }
.px .bondRow .chip.lv { border-color: #e2c26f; }
.px .chip.due { border-color: var(--accent); }

/* bars: square ends, an outline and a light top row on the fill */
.px .bar { height: 12px; border-radius: 0; border: var(--p) solid var(--o); background: #fbe7ef; clip-path: var(--corner); }
.px .bar i { border-radius: 0; background-image: linear-gradient(#ffffff66 0 var(--p), transparent var(--p)); }
.px .bar.xp { height: 12px; }
.px .bar.xp i { background-color: #ff9bb8; background-image: linear-gradient(#ffffff66 0 var(--p), transparent var(--p)); }
.px .bar.xp.capped i { background-color: #d9c3cc; }
/* the needs' bars as the level's: square, the same pink and light top (10-31, user: "경험치바랑 허기, 그런거랑 바 느낌이
   달라보이네"); low, red */
.px .careRow.tiles .bar { border-radius: 0; }
.px .careRow.tiles .bar b { background-color: #ff5c8d !important; }   /* stronger than the old row's: on a tile, not the panel */
.px :is(.needBars, .careRow.tiles) .bar b { border-radius: 0; background-color: #ff9bb8; background-image: linear-gradient(#ffffff66 0 var(--p), transparent var(--p)); }
.px .careRow.tiles .bar.low b, .px .needBars .need.low .bar b { background-color: var(--bad, #e0584f); }
.px .timebar { height: 10px; }
.px .timebar i { background-color: #8fd0ff; background-image: linear-gradient(#ffffff66 0 var(--p), transparent var(--p)); }

/* round things become pixel squares */
.px .swatch { border-radius: 0; }
.px .dot, .px .bookRow .dot { border-radius: 0; }

/* the tab bar */

/* pixel icons (tools/pixel_icons.py; src/pxui.js swaps the emoji for them): --i is the icon's place in the strip,
   --s its size on screen, from the text it sits in so it fits it (user: "버튼이나 영역에 넘치는 아이콘", 10-31 "폰트
   사이즈랑 아이콘이랑 안맞는곳이 있어"): the text's size and 4 — 16 by 12 px text, 20 by 16, 24 by 20 — rounded to 4 px,
   whole screen pixels per icon pixel on a 3x phone; 24 alone in the tab bar, 32–36 a game's, a room's or an empty
   place's own; centred on the text a third of an em up (user: "아이콘 세로, 텍스트랑 중앙정렬") */
.px .ico { --i: 0; --s: calc(1em + 4px); --s: round(nearest, calc(1em + 4px), 4px); display: inline-block; width: var(--s); height: var(--s); vertical-align: calc(0.33em - var(--s) / 2); margin: 0 1px;
  background: url("assets/ui/icons.png") calc(var(--i) * var(--s) * -1) 0 / calc(var(--s) * 44) var(--s) no-repeat;   /* 44 = the icons in the strip (tools/pixel_icons.py) */
  image-rendering: pixelated; font-style: normal; }
.px .ico.glued { margin-right: .25em; }   /* written right against its text, '🦴12' (pxui.js) */
.px .ico-ball { --i: 1; } .px .ico-bubbles { --i: 2; } .px .ico-paw { --i: 3; } .px .ico-share { --i: 4; } .px .ico-sofa { --i: 5; }
.px .ico-house { --i: 6; } .px .ico-pad { --i: 7; } .px .ico-dress { --i: 8; } .px .ico-friends { --i: 9; } .px .ico-trophy { --i: 10; }
.px .ico-gear { --i: 11; } .px .ico-camera { --i: 12; } .px .ico-gift { --i: 13; } .px .ico-basket { --i: 14; } .px .ico-rope { --i: 15; }
.px .ico-cup { --i: 16; } .px .ico-tennis { --i: 17; } .px .ico-sound { --i: 18; } .px .ico-mute { --i: 19; } .px .ico-scissors { --i: 20; }
.px .ico-book { --i: 21; } .px .ico-star { --i: 22; } .px .ico-tree { --i: 23; } .px .ico-pumpkin { --i: 24; } .px .ico-bell { --i: 25; }
.px .ico-pot { --i: 26; } .px .ico-hammer { --i: 27; } .px .ico-bed { --i: 28; } .px .ico-heart { --i: 29; } .px .ico-cart { --i: 30; }
.px .ico-cookie { --i: 31; } .px .ico-bread { --i: 32; } .px .ico-herb { --i: 33; } .px .ico-carrot { --i: 34; }
.px .ico-left { --i: 35; } .px .ico-right { --i: 36; } .px .ico-back { --i: 37; } .px .ico-next { --i: 38; } .px .ico-close { --i: 39; } .px .ico-plus { --i: 40; } .px .ico-menu { --i: 41; } .px .ico-capsule { --i: 42; } .px .ico-addhome { --i: 43; }
/* the arrows and the cross are ink: white on a pink button, faint where they stand for 'none' */
.px :is(.pill.accent, .big, .banner) :is(.ico-left, .ico-right, .ico-back, .ico-next, .ico-close, .ico-plus) { filter: brightness(0) invert(1); }
.px .noneX .ico-close { --s: 24px; opacity: 0.55; }
.px .modalX .ico { --s: 12px; margin: 0; }   /* a window's ✕ smaller than its 24 px round button (user: "x 아이콘도 너무 크네"): the icon's own 12 cells */
.px .gameCard .em .ico { --s: 36px; }
.px .empty { border-radius: 0; border: var(--p) dashed var(--o); }
.px .empty .emptyIcon .ico { --s: 32px; }
.px .empty.slim .emptyIcon .ico { --s: 24px; }
.px .coins .ico { --s: 20px; }   /* by the bones' number (16 px), not the chip's small print */

/* pixel pictures in the page stay in whole pixels when the browser scales them */
.px .tray .tile canvas, .px .tile canvas, .px .friend canvas { image-rendering: pixelated; }
.px #decorate .hudBottom { border-radius: 0; border-top: var(--p) solid var(--o); }
.px .decoDyes .dye { border-radius: 0; clip-path: var(--corner); border: var(--p) solid var(--o); box-shadow: inset 0 0 0 var(--p) #ffffffaa; }
.px .decoDyes .dye.on { border-color: var(--o-strong); box-shadow: inset 0 0 0 var(--p) #fff; transform: translateY(calc(-1 * var(--p))); }
.px .decoDyes .dye.locked { opacity: 1; background-image: linear-gradient(135deg, transparent 0 40%, #ffffff99 40% 60%, transparent 60%); }
.px #board li.note { clip-path: none; }
