:root { color-scheme: dark; --story-font: Georgia, "Times New Roman", serif; --story-size: 42px; --flow-font: Helvetica, Arial, sans-serif; --gallery-font: Inter, sans-serif; }
/* The translation's special letters (private-use U+E000-E2FF, the game font's) are turned into the story font's own
   letters, italic or flipped (textbox.js; #text .ch.mirror, .ch.flip). */
html, body { margin: 0; height: 100%; background: #000; overflow: hidden; }
#stage { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; transform-origin: 0 0; overflow: hidden; background: #000; user-select: none; font-family: var(--story-font); color: #fff; }
#gl, #movie { position: absolute; inset: 0; width: 1920px; height: 1080px; }
/* the touch ring (touchfx.js) over everything, as the game draws it last */
#touchfx { position: absolute; inset: 0; width: 1920px; height: 1080px; pointer-events: none; z-index: 50; }
#movie { display: none; background: #000; object-fit: contain; }
#movie-pic { position: absolute; inset: 0; width: 1920px; height: 1080px; display: none; }
/* A story movie's cover (native 0x40940): black, or white for op1_arc and ed03_ciel, over the picture as it comes and goes. */
#movie-cover { position: absolute; inset: 0; width: 1920px; height: 1080px; display: none; pointer-events: none; }
#panel { position: absolute; inset: 0; pointer-events: none; opacity: 0; background: url("/assets/ui/DISP_PARTS_JA/txtwindow01-1920.webp") 0 0 / 100% 100% no-repeat; }
/* The row pitch is the game's, measured on a native page (rows 77.5 px apart: 0x39180 reads the patched cell layout), and the box's top keeps the first row where it was. */
#text, .logpage { position: absolute; left: 265px; top: 146px; width: 1390px; bottom: 0; font-family: var(--story-font); font-size: var(--story-size); font-weight: 400; line-height: 77.5px; white-space: pre-wrap; pointer-events: none; text-shadow: 0 1px 3px rgba(0,0,0,.85), 0 0 6px rgba(0,0,0,.45); }
#text { opacity: 0; }
/* Balloon text (the Q&A corners) is in the game's third face, ja3/SeuratPro-M.otf (0x6e0d0 flag 0x800000 -> 0xbdc2c code 0x18 -> font 2; N2-21),
   set proportionally as the story text is. */
@font-face { font-family: "SeuratPro"; src: url("/assets/fonts/SeuratPro-M.otf") format("opentype"); font-display: swap; }
#text.balloon { font-family: "SeuratPro", var(--story-font); }
/* The current line in a second balloon (textbox.js placeCurrent): taken out of the page's flow and put at that balloon's text origin. */
#text .second { position: absolute; display: block; }
/* Earlier lines dim frame by frame (textbox.js dimLines, native 0x391a0); a line with @x goes on the previous row 2
   units after its end (0xa8190). */
:is(#text, .logpage) .seg.glued { margin-left: 6px; }
/* @c1-@c5: the engine's text colour table (main image 0x3C99D6, RGBA); a run of them is a span inside the message */
:is(#text, .logpage) .color1 { color: rgb(255 0 0); }
:is(#text, .logpage) .color2 { color: rgb(50 136 255); }
:is(#text, .logpage) .color3 { color: rgb(16 16 16); }
:is(#text, .logpage) .color4 { color: rgb(170 170 170); }
:is(#text, .logpage) .color5 { color: rgb(0 0 255); }
/* @c6-@c9: the outlined face, its outline from 0x34dcb0 (red, dark grey, black, white), in place of the shadow */
:is(#text, .logpage) .edge6 { --edge: rgb(255 0 0); }
:is(#text, .logpage) .edge7 { --edge: rgb(40 40 40); }
:is(#text, .logpage) .edge8 { --edge: rgb(0 0 0); }
:is(#text, .logpage) .edge9 { --edge: rgb(255 255 255); }
:is(#text, .logpage) .edge6, :is(#text, .logpage) .edge7, :is(#text, .logpage) .edge8, :is(#text, .logpage) .edge9 { text-shadow: -2px 0 var(--edge), 2px 0 var(--edge), 0 -2px var(--edge), 0 2px var(--edge), -1.4px -1.4px var(--edge), 1.4px -1.4px var(--edge), -1.4px 1.4px var(--edge), 1.4px 1.4px var(--edge); }
:is(#text, .logpage) .ch { opacity: 0; }
:is(#text, .logpage) .ch.on { opacity: 1; }
:is(#text, .logpage) .ch.mirror { display: inline-block; transform: scaleX(-1); }
/* The patch's bank 2 (U+E100): mirrored and italic, a slanted line seen in a mirror. */
:is(#text, .logpage) .ch.mirror.italic { font-style: italic; }
:is(#text, .logpage) rt.italic, :is(#text, .logpage) ruby.italic { font-style: italic; }
/* A run of U+2015 is one element whose dashes overlap, so it draws as one line as in the game, its shadow painted once
   under it (textbox.js setDashJoin); the margin gives the last dash its advance back. */
:is(#text, .logpage) .dashrun { letter-spacing: var(--dash-join, -0.29em); margin-right: var(--dash-end, 0.29em); }
/* A run of U+25A0 is one solid bar (native 0xbdc2c, glyph U+00BD stretched over the run; N2-22), its top and bottom as on a native frame for the font's capitals:
   -0.064 to 0.814 of the game's em against capitals of 0.78, here against Georgia's capitals of 0.692. */
:is(#text, .logpage) .blockrun { display: inline-block; height: .78em; vertical-align: -.057em; background: currentColor; box-shadow: 0 1px 3px rgba(0,0,0,.85), 0 0 6px rgba(0,0,0,.45); }
:is(#text, .logpage) .ch.flip { display: inline-block; transform: scaleY(-1); }
/* Archaic speech (U+E180 letters): the game sets it in a serif italic apart from its ordinary italics; here a
   calligraphic face the system has, slightly larger as these run small, then the story font's italic (not the generic cursive, which is
   Comic Sans on Windows). */
:is(#text, .logpage) .archaic { font-family: "Apple Chancery", "Lucida Calligraphy", "Monotype Corsiva", "URW Chancery L", "TeX Gyre Chorus", var(--story-font); font-style: italic; font-size: 1.08em; }
:is(#text, .logpage) .mirror-word { white-space: nowrap; }
/* Letters fade in as they are typed, each over one letter interval (textbox.js type, native 0xc0684). */
/* [ber00] / [zap00] runs: a strip of the game's noise-bar glyphs over full-width placeholders (cells are 1em). */
:is(#text, .logpage) .glyph { display: inline-block; height: 1em; line-height: 1em; vertical-align: -0.18em; overflow: hidden; color: transparent; text-shadow: none; white-space: nowrap; background: url("/assets/ui/DISP_PARTS_JA/bf_with_edge68x68_2.webp") no-repeat; background-size: 21em 29em; }
.notext #text, .notext #panel, .notext #click-mark { visibility: hidden; }
/* F1110's note (native 0x391a0, DISP_PARTS_JA texture 69): full screen over the window, drawn also while it is closed. */
#note { position: absolute; inset: 0; width: 1920px; height: 1080px; display: none; opacity: 0; pointer-events: none; background: url("/assets/ui/DISP_PARTS_JA/tw___________.webp") 0 0 / 100% 100% no-repeat; }
/* Click marks (native 0x38ec0): 105 cells of 39 x 39, one every other frame (3.5 s a loop), drawn at (0.36, 0.45) of the
   640 x 448 scale (1.08 x 1.085 on the stage), fading in at 0.1 a frame; the page mark at half alpha. */
#click-mark { position: absolute; width: 42.12px; height: 42.31px; display: none; pointer-events: none; background: url("/assets/ui/DISP_PARTS_JA/lineBreak_a.webp") 0 0 / 4422.6px 42.31px no-repeat; animation: markstep 3.5s steps(105) infinite, markin calc(10s / 60) linear; }
/* The page mark: 105 cells of a loop on the sheet, but the rectangle table's last entry (0x5730a0 entry 104) repeats the one before it: cell 104 of the sheet is empty (N2-111). */
#click-mark.page { background-image: url("/assets/ui/DISP_PARTS_JA/pageBreak_a.webp"); opacity: .5; animation-name: markpage, markin; }
@keyframes markpage { 0% { background-position: 0 0; animation-timing-function: steps(104); } 99.0476% { background-position: -4380.48px 0; animation-timing-function: steps(1, start); } 100% { background-position: -4338.36px 0; } }
@keyframes markstep { to { background-position: -4422.6px 0; } }
@keyframes markin { from { opacity: 0; } }
#choices { position: absolute; inset: 0; display: none; }
/* Choices (native 0x84e50): rows of the story's text on the page; the glow is a blurred copy of the label added in cyan
   (colour 0.44, 1, 1; 0.75, 1, 1 once taken). 0x83e50 draws the labels into a picture of their own in a heavier style
   (0xa8b90: 0xc1074(.., 2)) and blurs it with 0xa0a90(2, 0, -2): 13 taps 1.5 px apart, across and down twice over, a
   sigma of about 4.3 px. On a native frame the halo is 0.77 of the visible label blurred by that much: the stroke here
   stands in for the heavier letters at the draw's level of 0.5. */
.choice { position: absolute; padding: 0; margin: 0; width: 1455px; text-align: left; white-space: pre; font: var(--story-size) var(--story-font); color: #fff; background: none; border: 0; cursor: pointer; outline: none; text-shadow: 0 1px 3px rgba(0,0,0,.85), 0 0 6px rgba(0,0,0,.45); }
.choice .ch { opacity: 0; }
.choice .ch.on { opacity: 1; }
.choice-glow { position: absolute; left: 0; top: 0; color: rgb(112 255 255); mix-blend-mode: plus-lighter; opacity: 0; text-shadow: none; pointer-events: none; filter: blur(4.27px); -webkit-text-stroke: 2.6px currentColor; }
.choice-glow.taken { color: rgb(192 255 255); }
.fx-add { mix-blend-mode: plus-lighter; }
.stretch { background-size: 100% 100%; }
.flare-tint { filter: url("#tint-flare"); }
#ui { position: absolute; inset: 0; display: none; font-family: system-ui, sans-serif; }
.page { position: absolute; inset: 0; overflow: hidden; }
.sp { position: absolute; background-repeat: no-repeat; pointer-events: none; }
.spbtn { position: absolute; background-color: transparent; background-repeat: no-repeat; border: 0; padding: 0; cursor: pointer; outline: none; }
.pulse { animation: pulse 2.4s ease-in-out infinite; }
/* "Press any button": up and down at 1/60 a frame, from nothing (native 0x8e200 state 9) */
.blink { animation: blink 2s linear infinite; }
@keyframes blink { 0% { opacity: 0; } 50% { opacity: 1; } 100% { opacity: 0; } }
.blackout { position: absolute; inset: 0; background: #000; pointer-events: none; }
.fxcanvas { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; pointer-events: none; }
.lumi { mix-blend-mode: plus-lighter; opacity: 0; }
.menubg, .menufg { position: absolute; inset: 0; }
.menubg { pointer-events: none; }
/* The menu's foreground level (native 0xb359f4): 0x4c370 draws each piece at it, so the additive cursor keeps adding to what is under the menu. */
.menufg .sp, .menufg .scene-name { opacity: var(--lv, 1); }
.menufg .nowplaying, .menufg .np-label { opacity: var(--lv, 1); }
.menufg .nowplaying .sp { opacity: 1; }
.cursorline { transform-origin: 50% 0; opacity: 0; mix-blend-mode: plus-lighter; }
.cursor { mix-blend-mode: plus-lighter; }
.gl-cursorline { transform-origin: 50% 50%; }
.title-btn > .sp { pointer-events: none; }
@keyframes pulse { 50% { opacity: .35; } }
/* The menu's blurred background is drawn by the renderer (renderer.js setMenuBlur: the engine's Gaussian, faded in over
   12 frames, no darkening). The text window is not part of it: on native frames the window goes as the menu's level rises and shows no
   more until the menu has gone (--under-menu, ui.js system). */
.menu-blur #text, .menu-blur #panel, .menu-blur #panel2, .menu-blur #click-mark, .menu-blur #note { filter: opacity(var(--under-menu, 0)); }
.scene-name { position: absolute; right: 96px; top: 42px; width: 420px; text-align: right; font: 600 22px system-ui, sans-serif; color: #123; pointer-events: none; }
/* The chapter at the header's left (ui.js chapterTitle), after the game's picture of it (system_phasetitle_ja): the day's figure, a long thin
   stroke, the name in a chancery italic, white, on one line. */
.chapter { position: absolute; left: 20px; top: 0; height: 84px; display: flex; align-items: center; white-space: nowrap; color: #fff; pointer-events: none; }
.menufg .chapter { opacity: var(--lv, 1); }
.chapter-day { position: relative; top: 9px; font: 400 92px/84px "Hoefler Text", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif; letter-spacing: 6px; font-variant-numeric: lining-nums; }
.chapter-stroke { flex: none; position: relative; top: 2px; width: 68px; height: 70px; margin: 0 2px 0 6px; background: linear-gradient(to bottom right, transparent calc(50% - 1.6px), #fff calc(50% - 1px), #fff calc(50% + 1px), transparent calc(50% + 1.6px)); }
.chapter-name { font-family: "Apple Chancery", "Lucida Calligraphy", "Monotype Corsiva", "URW Chancery L", "TeX Gyre Chorus", Georgia, serif; font-style: italic; line-height: 84px; padding-right: 12px; position: relative; top: 2px; }
.chapter-name.struck { text-decoration: line-through; text-decoration-thickness: 2px; }
/* The music playing (ui.js nowPlaying), in the header's band left of the scene name and set as it is: a turning disc, then the track's
   title, the two together ending where the box ends; a title too long for the box is cut with an ellipsis, so it never reaches the scene
   name. The disc is the Music Player's knob (music_soundbtn: cells of 80 x 88, the knob a circle 22 px across about (43, 43.5)): the lit
   cell drawn larger and turning, a turn every 2 s as the auto ring's, with the plain cell small at its centre. */
.nowplaying { position: absolute; top: 40px; height: 32px; display: flex; align-items: center; justify-content: flex-end; gap: 6px; pointer-events: none; }
/* "Audio Track" above the band's line: a small picture drawn in the lettering of the band's own "Note." (ui.js noteLabel) */
.np-label { position: absolute; pointer-events: none; }
.np-title { flex: 0 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font: 600 22px/32px system-ui, sans-serif; color: #123; }
.np-disc { position: relative; flex: none; width: 36px; height: 32px; }
/* (the cell is placed so that the knob's centre, (43, 43.5) in it, is the disc's: 18, 16) */
.np-turn { position: absolute; left: -25px; top: -27.5px; width: 80px; height: 88px; }
.np-turn, .np-hole { transform-origin: 43px 43.5px; }
.np-turn { transform: scale(1.3); animation: npturn 2s linear infinite; }
.np-turn .sp { left: 0; top: 0; }
.np-hole { transform: scale(.34); }
@keyframes npturn { from { transform: scale(1.3) rotate(0deg); } to { transform: scale(1.3) rotate(360deg); } }
/* The hint bar (ui.js helpBar): the game's band (native 0x4a8f0: (1, 60, 101) at half alpha from 424.36 to 449 of 640 x 448,
   1023 px down, its entries from x 55 px), with the keys and the mouse's part of each entry in place of the controller's
   buttons (help_key) and label art (help_txt_ja). */
.helpbar { position: absolute; left: 0; right: 0; top: 1023px; bottom: 0; display: flex; align-items: center; gap: 30px; box-sizing: border-box; padding-left: 55px; background: rgba(1,60,101,.5); color: #e8f1fb; font: 20px/1 var(--gallery-font), system-ui, sans-serif; white-space: nowrap; pointer-events: none; }
.hint { display: inline-flex; align-items: center; gap: 7px; }
.hint kbd { display: inline-block; min-width: 14px; padding: 5px 9px 6px; border: 1px solid rgba(232, 241, 251, .7); border-radius: 6px; background: rgba(4, 22, 48, .45); font: 600 16px/1 var(--gallery-font), system-ui, sans-serif; letter-spacing: .5px; text-align: center; }
.hint-label { margin-left: 3px; letter-spacing: .5px; }
/* Save slots (native 0x4f240): four to a page at (133.67, 36.92 + 93.75 i) of 640 x 448, i.e. (401, 89 + 226 i);
   save_win's frame cell (32, 32)-(992, 304), or (31, 336)-(991, 608) for the chosen one, drawn from the slot's corner;
   the thumbnail at (151, +23.23), 248 x 140; the chapter's title art (savetitle) at (253.33, +50.19). */
.slotlist { position: absolute; left: 401px; top: 89px; width: 980px; height: 906px; overflow: auto; display: flex; flex-direction: column; scrollbar-width: none; }
.slot { position: relative; flex: none; width: 960px; height: 226px; background: none; border: 0; padding: 0; cursor: pointer; outline: none; text-align: left; }
.slotbg { position: absolute; left: 0; top: 0; width: 960px; height: 272px; background: url("/assets/ui/SAVE_PARTS_JA/save_win.webp") -32px -32px no-repeat; pointer-events: none; }
.slotbg.hi { background-position: -31px -336px; }
.slotflash { position: absolute; left: 0; top: 0; width: 960px; height: 272px; background: url("/assets/ui/SAVE_PARTS_JA/save_win.webp") -31px -336px no-repeat; mix-blend-mode: plus-lighter; opacity: 0; pointer-events: none; }
.slotflash.go { animation: slotflash calc(5s / 60) linear; }
@keyframes slotflash { from { opacity: var(--a, 1); } to { opacity: 0; } }
/* The save screen's level (native 0xf1f440): 0x4f240 draws each piece at it, so the pieces take it one by one and not the page as a layer. */
.savefx .savea, .savefx .slotbg, .savefx .slot img, .savefx .slotdigits .sp, .savefx .slottitle, .savefx .slotscene, .savefx .slotnone,
.savefx .saveinfo .sp, .savefx .savenote, .savefx .scrollbar, .savefx .helpbar .hint, .savefx .slotlabel, .savefx .slotauto, .savefx .slotempty { opacity: var(--a, 1); }
.savefx .helpbar { background: rgba(1, 60, 101, calc(.5 * var(--a, 1))); }
/* Closing, the list is emptied first (0x50fc0 state 5): the rows' pictures and text and the panel go at once, the empty row windows fade. */
.savefx.save-out .slot img, .savefx.save-out .slotdigits, .savefx.save-out .slottitle, .savefx.save-out .slotscene, .savefx.save-out .saveinfo, .savefx.save-out .slotnone,
.savefx.save-out .slotlabel, .savefx.save-out .slotauto, .savefx.save-out .slotempty { visibility: hidden; }
/* A row's name (ui.js savesScreen): the slot's number or "Quick save" at the right of its chapter title, where an automatic save shows the game's own label (saveauto);
   an empty slot says so. */
.slotlabel { position: absolute; left: 656px; top: 127px; width: 228px; text-align: right; font: 600 24px/28px var(--gallery-font), system-ui, sans-serif; letter-spacing: 1px; color: #123; white-space: nowrap; pointer-events: none; }
.slotempty { position: absolute; left: 359px; top: 92px; font: 500 34px/42px Georgia, serif; color: rgba(18, 34, 51, .4); pointer-events: none; }
.slot img { position: absolute; left: 52px; top: 56px; width: 248px; height: 140px; object-fit: cover; }
.slotdigits { position: absolute; left: 345px; top: 33px; width: 560px; height: 64px; }
.slottitle { position: absolute; left: 359px; top: 117px; height: 48px; display: flex; align-items: center; white-space: nowrap; color: #111; pointer-events: none; }
/* (ui.js savesScreen: text after the game's picture of the chapter, savetitle: a large light figure, a thin stroke, the name in a narrow face) */
/* (the figure a little larger than the name, not the picture's twice its size, now that the name is larger) */
.slot-day { font: 300 31px/48px "Ubuntu", "Helvetica Neue", "Segoe UI", system-ui, sans-serif; letter-spacing: .5px; }
.slot-stroke { flex: none; width: 22px; height: 24px; margin: 2px 6px 0 3px; background: linear-gradient(to bottom right, transparent calc(50% - 1.2px), #111 calc(50% - .6px), #111 calc(50% + .6px), transparent calc(50% + 1.2px)); }
.slot-chapter { font: 400 26px/48px "Ubuntu Condensed", "PT Sans Narrow", "Arial Narrow", "Roboto Condensed", var(--flow-font); }
.slot-chapter.alone { font-size: 31px; letter-spacing: .5px; }
.slot-chapter.struck { text-decoration: line-through; text-decoration-thickness: 1.5px; }
/* The scene name under the chapter (native 0x50b10: SYSMES 395 + F022 at 22 x 29.5 units right of and below the cell). */
.slotscene { position: absolute; left: 425px; top: 174px; width: 520px; font: 600 22px system-ui, sans-serif; color: #123; white-space: nowrap; overflow: hidden; pointer-events: none; }
.slotnone { padding: 380px 0 0 0; text-align: center; font: 500 40px Georgia, serif; color: #123; }
.saveinfo { position: absolute; left: 1360px; top: 95px; width: 472px; height: 892px; }
.savenote { position: absolute; left: 34px; top: 560px; width: 404px; font: 24px/1.45 Georgia, serif; color: #123; }
/* The system's windows have their own layer over every screen (the task table 0x47bf0: notices 110, dialogs 120; only the Back button and the touch ring are drawn after them), so a window that is fading out carries on over whatever the answer opened. */
#sysui { position: absolute; inset: 0; z-index: 20; pointer-events: none; }
.dialog { position: absolute; inset: 0; pointer-events: auto; z-index: 1; }
.dialog.notice { z-index: 0; }
/* dialog_win centred at (320, 224) of 640 x 448 (native 0x4ae90), scaled about its centre as it opens and closes. */
.dialog-win { position: absolute; left: 548px; top: 332px; width: 824px; height: 416px; transform-origin: 50% 50%; pointer-events: none; }
/* The question: its first line where the game draws it (ink from row 452, 0x4ae90 at y 184 of 448), a second line 64 px below it (flags 0x120 give the text no vertical centring, N2-156), checked on a native frame. */
.dialog-q { position: absolute; left: 548px; top: 437px; width: 824px; text-align: center; font: 500 40px/64px Georgia, serif; color: #fff; white-space: pre-line; }
/* A notice's text sits at y 214 of 448, where the question's sits at 184 (0x48540 against 0x4ae90). */
.dialog.notice .dialog-q { top: 509.3px; }
/* SELS and SELA (0x85900 / 0x85e40): the window at x 321 of 640, its question drawn smaller (scale 0.37 x 0.46 of the font's size, against the system question's 0.6 x 0.7) at y 224 - 42.31 s, s the window's scale, centred on the screen. */
.dialog.story .dialog-win { left: 551px; }
.dialog.story .dialog-q { font-size: 30px; line-height: normal; top: 437px; transform-origin: 412px 103px; }
/* The config's own layers (ui.js config): the screen's level (backdrop, tabs, help bar) and the page's, and its
   digits (config_number_ja, native 0x2cab0). */
.conffg, .confpage { position: absolute; inset: 0; }
/* both cover the screen but take the pointer only where they have something: the system menu's column under them and the tabs and Reset under the page stay pressable */
.conffg, .confpage { pointer-events: none; }
.conffg > .confbtn, .confpage > .confscroll, .confpage > .scrollstrip { pointer-events: auto; }
.confdigits { position: absolute; left: 0; top: 0; pointer-events: none; }
/* a slider's bar (ui.js confSlider): a press anywhere along it puts the knob there */
.conftrack { position: absolute; cursor: pointer; touch-action: none; }
/* The Controls page (ui.js buildControlsPage): headings and rows after the game's own page (conf_manual0_ja: a blue-violet
   strip over a dark panel, white rows parted by thin lines), and a button for each key. */
.keyhead, .keyrow, .keycap, .keyslot { position: absolute; box-sizing: border-box; font-family: var(--gallery-font), system-ui, sans-serif; white-space: nowrap; }
.keyhead { padding-left: 24px; font-size: 22px; letter-spacing: .5px; color: #fff; background: linear-gradient(90deg, rgba(86, 104, 196, .9), rgba(96, 150, 200, .75) 55%, rgba(120, 170, 190, .55)); pointer-events: none; }
.keynote { position: absolute; text-align: right; font: 18px var(--gallery-font), system-ui, sans-serif; letter-spacing: .4px; color: rgba(255, 255, 255, .85); white-space: pre; pointer-events: none; }
.keyrow { padding-left: 26px; font-size: 30px; color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .7); background: rgba(8, 14, 44, .72); border-bottom: 1px solid rgba(120, 150, 220, .45); pointer-events: none; }
.keycap { padding: 0 16px; font-size: 22px; font-weight: 600; letter-spacing: 1px; color: #e8f1fb; border: 1px solid rgba(232, 241, 251, .55); border-radius: 6px; background: rgba(4, 22, 48, .5); pointer-events: none; }
.keyslot { padding: 0; font-size: 22px; font-weight: 600; letter-spacing: 1px; color: #fff; border: 1px solid rgba(232, 241, 251, .7); border-radius: 6px; background: rgba(30, 60, 120, .55); cursor: pointer; outline: none; }
.keyslot.none { color: rgba(232, 241, 251, .45); border-color: rgba(232, 241, 251, .3); }
.keyslot.sel { background: rgba(70, 150, 240, .85); border-color: #bff; box-shadow: 0 0 10px rgba(120, 220, 255, .9); color: #fff; }
.keyslot.wait { background: rgba(120, 235, 255, .95); border-color: #fff; color: #0b3a66; box-shadow: 0 0 14px rgba(150, 245, 255, 1); }
.confnum { position: absolute; text-align: right; font: 32px Georgia, serif; letter-spacing: 3px; color: #fff; pointer-events: none; }
.confsample { position: absolute; left: 756px; font: 40px var(--story-font); color: #fff; pointer-events: none; line-height: 64px; }
.confscroll::-webkit-scrollbar, .slotlist::-webkit-scrollbar { display: none; }
/* The backlog (ui.js backlog, native 0x27d10): a black veil at 0.75 of its alpha over the held scene, and the page drawn
   as the text window drew it (.logpage shares #text's rules) with the help and scroll bars at its alpha. */
.logveil { position: absolute; inset: 0; background: #000; opacity: 0; pointer-events: none; }
.logfg { position: absolute; inset: 0; opacity: 0; }
/* The scrolling log (ui.js backlog): the pages one under another, each as the text window drew it, a rule between them; the line under
   the cursor lit; a line with a voice has a speaker mark in the margin. */
.logscroll { position: absolute; left: 0; top: 0; width: 1920px; height: 1023px; overflow-x: hidden; overflow-y: auto; scrollbar-width: none; overscroll-behavior: contain; }
.logscroll::-webkit-scrollbar { display: none; }
.loglist { padding: 40px 0 60px; }
.logscroll .logpage { position: relative; left: 265px; top: auto; bottom: auto; pointer-events: auto; padding: 26px 0 40px; border-bottom: 1px solid rgba(190, 225, 255, .22); }
.logscroll .logpage:last-child { border-bottom: 0; }
.logrec.jump { cursor: pointer; }
/* the line under the cursor glows as a choice's row does (the label's blurred copy added in cyan, 0.44, 1, 1): no box behind it */
.logrec.sel { text-shadow: 0 0 5px rgba(112, 255, 255, .95), 0 0 14px rgba(112, 255, 255, .8), 0 0 28px rgba(64, 200, 255, .55), 0 1px 3px rgba(0, 0, 0, .85); }
.logvoice { position: absolute; width: 46px; height: 46px; margin: 16px 0 0 -66px; padding: 0; border: 1px solid rgba(232, 241, 251, .55); border-radius: 50%; cursor: pointer; outline: none; opacity: .7;
  background: rgba(4, 22, 48, .5) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M4 9v6h4l5 4V5L8 9H4zm11.5 3a3.5 3.5 0 0 0-2-3.15v6.3a3.5 3.5 0 0 0 2-3.15zm-2-7.7v2.06a5 5 0 0 1 0 9.28v2.06a7 7 0 0 0 0-13.4z'/%3E%3C/svg%3E") center / 34px no-repeat; }
.logvoice:hover { opacity: 1; border-color: #9fe8ff; box-shadow: 0 0 8px rgba(120, 220, 255, .9); }
/* The game's own scroll bar (ui.js scrollBar) replaces the browser's on these lists. */
.scrollbar { pointer-events: none; }
.scrollstrip { position: absolute; cursor: pointer; touch-action: none; }
/* The quick bar (ui.js buildPanel), on the mode panel's backdrop and with its motion: the panel (native 0x4e170 / 0x4de10)
   comes down from 43.14 units (104 px) above over 20 frames, without fading, eased "type 2, out": quadratic out, which
   is exactly this cubic Bezier. */
/* 0x4de10 / 0x4e170: the bar is placed by one level through quad out (0xe1bfc); the level rises 0.05 a frame opening and falls 0.05
   a frame closing, so closing replays the opening backwards: y = -104 tau^2, slow at first (N2-105). */
.modepanel { position: absolute; left: 0; top: 0; width: 1920px; height: 96px; z-index: 5; transform: translateY(-104px); visibility: hidden; transition: transform calc(20s / 60) cubic-bezier(.333333, 0, .666667, .333333), visibility calc(20s / 60); }
.modepanel.on { transform: none; visibility: visible; transition: transform calc(20s / 60) cubic-bezier(.333333, .666667, .666667, 1), visibility calc(20s / 60); }
/* Its buttons are the panel's own plates (ui.js quickBarArt: a sheet made from mode_panel_btn_ja, a column a button, the rows off, normal, under the
   cursor, on or pressed). Until the sheet is made, or where it cannot be, they are plain plates in the same four looks (r0 - r3). */
.qbtn { position: absolute; box-sizing: border-box; padding: 0; border: 1px solid rgba(255, 255, 255, .28); cursor: pointer; outline: none; white-space: nowrap; overflow: hidden;
  font: 400 22px/1 var(--gallery-font), system-ui, sans-serif; letter-spacing: .5px; text-transform: uppercase; color: #fff; text-shadow: 0 0 8px rgba(110, 195, 255, .95);
  background: linear-gradient(90deg, rgba(0, 7, 21, .4), rgba(14, 75, 132, .34) 50%, rgba(0, 7, 21, .4)) no-repeat; }
.qbtn.r2 { background-image: linear-gradient(90deg, rgba(32, 94, 179, .52), rgba(7, 159, 255, .52) 50%, rgba(32, 94, 179, .52)); }
.qbtn.r3 { background-image: linear-gradient(90deg, rgba(5, 165, 255, .52), rgba(69, 255, 255, .52) 50%, rgba(5, 165, 255, .52)); }
.qbtn.r0 { cursor: default; color: rgba(30, 30, 30, .62); text-shadow: 0 0 7px rgba(0, 0, 0, .5); background-image: linear-gradient(90deg, rgba(12, 12, 12, .4), rgba(99, 99, 99, .34) 50%, rgba(12, 12, 12, .4)); }
.qbtn.art { border: 0; font-size: 0; color: transparent; text-shadow: none; }
/* The pointer goes out of sight when it has rested over the story (main.js). */
#stage.idle, #stage.idle * { cursor: none !important; }
.fc-page { font-family: var(--flow-font); }
/* The gallery's music list, player and ending caption are set in Inter (fonts/, with its licence). */
@font-face { font-family: "Inter"; src: url("fonts/Inter-Latin-Variable.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }
.gl-page, .gl-content, .gl-title { position: absolute; inset: 0; }
.gl-title { pointer-events: none; }
.gl-item, .gl-thumb, .gl-control, .gl-movie, .gl-track { position: absolute; padding: 0; border: 0; background-color: transparent; background-repeat: no-repeat; cursor: pointer; outline: none; }
.gl-grid, .gl-music-list { position: absolute; overflow: hidden; }
.gl-grid-inner, .gl-music-rows { position: absolute; inset: 0; transition: transform .12s ease-out; }
.gl-layer { position: absolute; inset: 0; }
.gl-cursor { position: absolute; pointer-events: none; }
.gl-thumb-clip { position: absolute; inset: 0; clip-path: inset(14px 0 0 0); }
/* the viewer's backdrop: 0xba18's rectangle (0, 0, 1920 x 1081) in grey 0.847, behind the picture */
.gl-viewer { position: absolute; inset: 0; z-index: 10; background: rgb(216, 216, 216); cursor: pointer; }
.gl-viewer { overflow: hidden; touch-action: none; }
/* the hint band lies over the change's wipe (gallery.js viewer), so it stands still while the picture under it changes */
.gl-viewer-band { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.gl-wipe { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; pointer-events: none; z-index: 1; }
.gl-movie-cover { position: absolute; inset: 0; z-index: 15; pointer-events: none; }
.fc-replay-cover { position: absolute; inset: 0; z-index: 15; opacity: 0; background: #000; pointer-events: none; }
.gl-now { position: absolute; pointer-events: none; }
.fc-help.gl-guide { top: 0; height: 1080px; display: block; padding: 0; background: none; pointer-events: none; }
.gl-crop { position: absolute; left: 0; top: 0; overflow: hidden; transform-origin: 0 0; }
.gl-crop img { position: absolute; left: 0; top: 0; max-width: none; transform-origin: 0 0; user-select: none; }
.gl-track { text-align: left; font: 28px/59px var(--gallery-font); letter-spacing: 4px; color: rgba(255, 255, 255, .55); white-space: nowrap; text-shadow: 0 1px 2px #000; }
.gl-music-rows.focused .gl-track.sel { color: #fff; }
.gl-now-title, .gl-now-by, .gl-time, .gl-volume { position: absolute; color: #fff; font-family: var(--gallery-font); pointer-events: none; font-variant-numeric: tabular-nums; }
.gl-now-title { font-size: 26px; line-height: 34px; text-align: center; letter-spacing: 2px; }
.gl-now-by { font-size: 26px; line-height: 32px; text-align: center; white-space: nowrap; }
.gl-time { font-size: 30px; line-height: 40px; text-align: center; letter-spacing: 3px; }
.gl-volume { font-size: 28px; line-height: 40px; text-align: right; letter-spacing: 2px; }
.gl-slider { position: absolute; cursor: pointer; }
.gl-knob { position: absolute; pointer-events: none; background-repeat: no-repeat; }
.gl-ending-btn { position: absolute; padding: 0; border: 0; background: transparent; cursor: pointer; outline: none; }
.gl-ending-face { pointer-events: none; }
.gl-ending-caption { position: absolute; left: 384px; top: 990px; width: 1440px; text-align: center; font: 30px var(--gallery-font); letter-spacing: 3px; color: #fff; text-shadow: 0 0 10px #5fd0ff, 0 1px 2px #000; pointer-events: none; }
.gl-movie-catcher { position: absolute; inset: 0; z-index: 20; cursor: pointer; }
/* isolation keeps the cursor's z-index inside the map, under a dialog drawn over the flowchart */
.fc-view { position: absolute; overflow: hidden; scrollbar-width: none; cursor: grab; isolation: isolate; touch-action: none; }
.fc-view::-webkit-scrollbar { display: none; }
.fc-view.drag { cursor: grabbing; }
.fc-map { position: relative; overflow: hidden; }
.fc-titles { position: absolute; left: 0; top: 0; pointer-events: none; }
/* A day's chapters (flowchart.js), after the game's pictures of them (flow_phasetitle: a narrow face, white, set right), written larger. */
.fc-chapter { position: absolute; box-sizing: border-box; text-align: right; white-space: nowrap; color: #fff; pointer-events: none;
  font: 400 25px/32px "Ubuntu Condensed", "PT Sans Narrow", "Arial Narrow", "Roboto Condensed", var(--flow-font); }
.fc-chapter s { text-decoration-thickness: 1.5px; }
div.fc-node { pointer-events: none; cursor: default; }
.fc-band { position: absolute; pointer-events: none; background: url("/assets/ui/MENU_PARTS_JA/flow_sam_bg_middle_fullhd.webp") repeat-y; }
.fc-line { pointer-events: none; }
.fc-node { position: absolute; padding: 0; border: 0; background-color: transparent; background-repeat: no-repeat; cursor: pointer; outline: none; }
.fc-node[aria-disabled="true"] { cursor: default; }
.fc-cursor { position: absolute; z-index: 1; pointer-events: none; background-repeat: no-repeat; }
.fc-preview { position: absolute; inset: 0; pointer-events: none; }
.fc-preview-image { position: absolute; object-fit: cover; }
.fc-preview-title, .fc-preview-note { position: absolute; overflow: hidden; white-space: pre-line; font-family: var(--flow-font); font-size: 24px; line-height: 32px; font-weight: 400; }
.fc-preview-title { color: #403987; white-space: nowrap; }
.fc-preview-note { color: #000; }
.fc-help { position: absolute; left: 0; right: 0; top: 1023px; height: 57px; display: flex; align-items: center; gap: 22px; padding-left: 55px; box-sizing: border-box; background: rgba(1,60,101,.5); color: #fff; font: 18px var(--flow-font); }
#mode-auto { position: absolute; right: 34px; top: 26px; display: none; pointer-events: none; background-repeat: no-repeat; }
/* The skip indicator (native 0x3b5f0): mode_disp's >> (plain skipping, state 5, at 0.6) or >>| (to the next choice,
   state 4), centred at (626.67, 38.16) of 640 x 448, fading in and out at 0.05 a frame. Task 0xe at priority 82 with the popup: under the
   system menu's background (83), the menu (84), the mode panel (85) and the backlog's veil (87), so no z-index and before #ui (N2-28). */
/* The black of a scene skip's countdown (main.js drawSkipBlack, native 0x3ef20): over the picture and the text window,
   under the interface, the popups and the skip indicator. */
#skip-black { position: absolute; inset: 0; background: #000; opacity: 0; pointer-events: none; }
#mode-skip { position: absolute; left: 1836px; top: 48px; width: 88px; height: 88px; pointer-events: none; background: url("/assets/ui/DISP_PARTS_JA/mode_disp.webp") -264px 0 no-repeat; opacity: 0; transition: opacity calc(20s / 60) linear; }
#mode-skip.on { opacity: 1; }   /* state 3: >> at full while skipping runs (N2-8) */
/* State 5: the toggle on, stopped at unread text. 0x3b5f0 draws the cell at 0.6 of the indicator's level, and the level only
   rises while the skip runs (0x40ed0 at 0x4194c puts the speed back to 1 there), so it falls 0.05 a frame: the >> dims and
   is gone in 20 frames, and comes back when skipping goes on. A native capture of the skip button pressed on such a
   line shows no indicator at all. */
#mode-skip.on.paused { opacity: 0; filter: opacity(.6); }
#mode-skip.on.countdown { opacity: 1; background-position: -352px 0; }   /* state 4: >>| only in a scene skip's countdown (N2-96) */
#mode-skip.on.held-under { opacity: 0; }   /* state 0: the fast-forward key with a screen up, the toggle off (main.js syncFastForward) */
/* The rewind indicator: states 1 (|<<, cell 0, Return to Previous Scene's countdown) and 2 (<<, cell 88, a rewind) at x 546.67
   of 640, fading at 0.25 a frame (0x3b5f0: five times faster while rewinding; N2-9). */
#mode-back { position: absolute; left: 1596px; top: 48px; width: 88px; height: 88px; pointer-events: none; background: url("/assets/ui/DISP_PARTS_JA/mode_disp.webp") -88px 0 no-repeat; opacity: 0; }   /* its level is set frame by frame (main.js backIconFrame) */
#mode-back.choice { background-position: 0 0; }
#mode-auto { width: 84px; height: 84px; background-image: url("/assets/ui/DISP_PARTS_JA/mode_ring_1.webp"); background-size: 100% 100%; animation: spin 2s linear infinite; }
@keyframes spin { to { rotate: 360deg; } }
#toast { position: absolute; right: 30px; bottom: 26px; font: 24px system-ui, sans-serif; background: rgba(0,0,0,.72); padding: 8px 16px; border-radius: 4px; display: none; pointer-events: none; }
.slot .saveauto { pointer-events: none; }
/* Config pages longer than the screen scroll under the tabs (system_bg is 1336 rows, voice_bg 2872). */
/* a config page: cut to x 407-1809, y 165-1023 (uifx.js CONFIG.clip); the inner part moves with the page's scroll (ConfigScroll) */
.confscroll { position: absolute; left: 407px; top: 165px; width: 1402px; height: 858px; overflow: hidden; }
.confscroll-inner { position: absolute; left: -407px; top: -165px; width: 1920px; }
.conflayer { position: absolute; left: 0; top: 0; width: 1920px; }
/* a widget's press area is its hit box; its cells reach past it */
.confbtn, .menucol { overflow: visible; }
.confsample span { opacity: 0; }
#panel2 { position: absolute; inset: 0; pointer-events: none; opacity: 0; }
/* The renderer draws the window's pictures into the canvas, before its display curve as the game does (renderer.js drawWindow, item 116);
   these elements only stand in until the pictures have loaded. */
.canvas-window #panel, .canvas-window #panel2 { visibility: hidden; }
.notext #panel2 { visibility: hidden; }
/* The balloons' click mark (DISP_PARTS_JA/pageBreak_ciel_a: 59 cells of 43 x 46, a cell every two frames). */
#click-mark.ciel { width: 46.44px; height: 49.68px; margin: 1.2px 0 0 6px; opacity: 1; background-image: url("/assets/ui/DISP_PARTS_JA/pageBreak_ciel_a-1920x1080.webp"); background-size: 2739.96px 49.68px; animation: markciel calc(118s / 60) steps(59) infinite, markin calc(10s / 60) linear; }
@keyframes markciel { from { background-position: 0 0; } to { background-position: -2739.96px 0; } }
.in-log #text, .in-log #panel, .in-log #panel2, .in-log #click-mark, .in-log #note { visibility: hidden; }
/* The engine's notices (popup_ja: 416 x 56 cells), at (0, 32) of 640 x 448. Task 0xe at priority 82 (0x3b4b0): over the scene and the
   covers, under the system menu's background (83), the menu (84) and the mode panel (85): under #ui and .modepanel (N2-131). */
#popup { position: absolute; left: 0; top: 77px; width: 416px; height: 56px; display: none; pointer-events: none; transform-origin: 0 0; background: url("/assets/ui/DISP_PARTS_JA/popup_ja.webp") no-repeat; }
/* A button's caption (ui.js Caption, native 0xae590): mode_help under a small face, the band at 0.7 of its level. */
.caption { position: absolute; left: 0; top: 0; width: 0; height: 0; display: none; pointer-events: none; z-index: 30; }
.caption-band { position: absolute; height: 48px; background: url("/assets/ui/DISP_PARTS_JA/mode_help.webp") 0 0 / 100% 100% no-repeat; }
.caption-text { position: absolute; white-space: nowrap; color: #fff; font: 20px/1.2 var(--story-font); }
/* The completion banner (native 0x91350, 960 x 540 units doubled): a band edged in (0.19, 0.25, 0.58) at half the
   alpha over black at three quarters, the text from x 401. */
.completion { position: absolute; left: 770px; top: 960px; width: 1108px; height: 73px; box-sizing: border-box; border: 1px solid rgba(49, 63, 148, .5);
  background: rgba(0, 0, 0, .753); color: #fff; font: 500 27px Georgia, serif; line-height: 73px; padding-left: 32px; white-space: nowrap; pointer-events: none; }
/* Return to Title and a script's end: the story going to black (0.02 a frame), under the interface. */
#story-black { position: absolute; inset: 0; width: 1920px; height: 1080px; background: #000; display: none; pointer-events: none; }
/* Quick Load's picture (native 0x4ae90): framed in black, centred, from y 200 of 448 units. */
.dialog-pic { position: absolute; left: 852px; top: 482px; width: 216px; height: 124px; background: #000; }
.dialog-pic img { position: absolute; left: 6px; top: 5px; width: 204px; height: 114px; object-fit: cover; }
/* The first visit's page (welcome.js): the reading column inside Config's inner panel, in the story's face and the game's lettering. */
.wl-scroll { left: 180px; top: 96px; width: 1560px; height: 927px; }
.wl-text { box-sizing: border-box; padding: 34px 150px 80px; color: #e8f1fb; font: 400 31px/48px var(--story-font); text-shadow: 0 1px 3px rgba(0, 0, 0, .85), 0 0 6px rgba(0, 0, 0, .45); }
.wl-text p { margin: 0 0 24px; }
.wl-text .wl-note { margin: -8px 0 26px; font-size: 27px; line-height: 38px; color: #bfeeff; text-align: center; }
.wl-text h2 { margin: 0 0 30px; padding-bottom: 22px; font: 400 58px/70px var(--story-font); color: #fff; text-shadow: 0 0 5px rgba(112, 255, 255, .95), 0 0 14px rgba(112, 255, 255, .8), 0 0 28px rgba(64, 200, 255, .55), 0 1px 3px rgba(0, 0, 0, .85); background: url("/assets/ui/MENU_PARTS_JA/underline.webp") 0 100% / 100% 16px no-repeat; }
.wl-text h3 { margin: 34px 0 10px; font: 400 38px/48px var(--story-font); color: #bfeeff; text-shadow: 0 0 10px rgba(110, 195, 255, .9), 0 1px 3px rgba(0, 0, 0, .85); }
.wl-logo { width: 336px; height: 389px; margin: 0 auto 26px; background: url("/assets/ui/TITLE_PARTS_JA/title_titlelog.webp") 0 0 / 100% 100% no-repeat; }
.wl-facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px 34px; margin: 30px 0 34px; }
.wl-fact { display: flex; flex-direction: column; gap: 2px; }
.wl-num { font: 400 46px/52px "PT Sans Narrow", "Ubuntu Condensed", "Arial Narrow", "Segoe UI", "Helvetica Neue", Arial, sans-serif; color: rgb(242 246 248); text-shadow: 0 0 9px rgba(110, 195, 255, .95); }
.wl-what { font: 400 24px/32px var(--story-font); color: #c9d8e6; }
.wl-rows { display: grid; grid-template-columns: 500px 1fr; gap: 12px 30px; margin: 14px 0 28px; align-items: baseline; }
.wl-name { font: 400 32px/40px "PT Sans Narrow", "Ubuntu Condensed", "Arial Narrow", "Segoe UI", "Helvetica Neue", Arial, sans-serif; color: #f2f6f8; text-shadow: 0 0 9px rgba(110, 195, 255, .75); overflow-wrap: anywhere; }
