/* The app's own Chinese handwriting face, subset to the four characters of
   扭蛋日记 and nothing else — 4.3 MB of CJK reduced to 2 KB. Loading a whole
   CJK font for one word would cost more than the rest of the page put
   together, and a system fallback would put the app's name in a face that
   appears nowhere in the app. */
@font-face{
  font-family:"JasonZH";
  src:url("assets/fonts/jason-cn.woff2") format("woff2");
  font-display:swap;
  unicode-range:U+626D,U+86CB,U+65E5,U+8BB0;
}

/* The app's own tokens, carried across so the page and the product are one
   world. --ink and --paper are lifted straight from www/index.html; --crayon is
   sampled from the red in the cover drawing, which is deeper than the app's UI
   red because it is wax on paper rather than a button. */
:root{
  --paper:#fefdfb;
  --paper-edge:#f5f2ed;
  --ink:#2a1d10;
  --ink-soft:#6b513a;
  --crayon:#c0472f;
  --rule:rgba(42,29,16,.16);
  --rule-soft:rgba(42,29,16,.09);
  --card:#ffffff;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    /* Not an inversion — a lamp turned down on the same paper. The ground keeps
       the warmth of the original so the drawings, which are graphite on
       transparent, still sit on something that reads as paper. */
    --paper:#17120e;
    --paper-edge:#1e1813;
    --ink:#f2ebe2;
    --ink-soft:#b8a795;
    --crayon:#e2795f;
    --rule:rgba(242,235,226,.18);
    --rule-soft:rgba(242,235,226,.10);
    --card:#1e1813;
  }
}
:root[data-theme="dark"]{
  --paper:#17120e; --paper-edge:#1e1813; --ink:#f2ebe2; --ink-soft:#b8a795;
  --crayon:#e2795f; --rule:rgba(242,235,226,.18); --rule-soft:rgba(242,235,226,.10);
  --card:#1e1813;
}

*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
html{-webkit-text-size-adjust:100%}
html,body{touch-action:manipulation}

/* The whole page is written in the app's own hand. This is only possible
   because the site is English-only: Schoolbell has no CJK glyphs, and a mixed
   script line would fall through to a system face mid-sentence. Handwriting
   runs small and loose, so the scale sits a point above a normal body size and
   the leading is opened up to keep it readable at paragraph length. */
body{
  background:var(--paper); color:var(--ink);
  font-family:"Schoolbell",ui-rounded,"Segoe Print",cursive;
  font-size:18px; line-height:1.95;
  padding:0 22px 40px;
  -webkit-font-smoothing:antialiased;
  /* The page is short — on a tall phone the content ends well above the bottom
     of the screen, leaving a dead band under the footer. Filling the viewport
     and letting the column centre itself spreads that leftover room evenly
     above and below, so it reads as composition rather than as the page having
     run out. svh rather than vh: vh on mobile means the height with the
     browser chrome hidden, which makes the layout jump as the toolbar
     collapses on scroll. */
  min-height:100vh;
  min-height:100svh;
  display:flex;
  flex-direction:column;
}
/* margin:auto rather than justify-content:center — when the content IS taller
   than the screen, centring a flex child clips its top beyond the scroll
   origin, and auto margins do not. */
.page{max-width:600px;width:100%;margin:auto}

/* ---------- hero ---------- */
.hero{padding:34px 0 4px;text-align:center}
.hero img{
  width:100%;max-width:420px;height:auto;display:block;margin:0 auto;
  /* The cover is drawn on an opaque white sheet. Multiply drops the sheet and
     leaves only the graphite and crayon, so the art sits on our paper instead
     of on a white rectangle a shade brighter than the page. */
  mix-blend-mode:multiply;
}
/* In the dark theme the art is inverted to chalk, so the sheet has to be
   dropped with screen instead — multiply there would erase the drawing rather
   than the sheet. The hue rotation keeps the red crayon red. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .hero img{
    filter:invert(1) hue-rotate(180deg) saturate(1.15);
    mix-blend-mode:screen;
  }
}
:root[data-theme="dark"] .hero img{
  filter:invert(1) hue-rotate(180deg) saturate(1.15);
  mix-blend-mode:screen;
}

/* ---------- download tiles ---------- */
.downloads{margin:38px 0 0}
.tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}

.tile{
  position:relative;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:7px; aspect-ratio:1; padding:10px 6px;
  text-decoration:none;color:inherit;
  transition:transform .16s ease;
}
/* The box is drawn, not bordered: an SVG path with a wobble in it, roughened
   by a turbulence filter so the stroke breaks up the way graphite does on
   paper. A CSS border cannot do this — it is always the same width and always
   perfectly smooth, which is exactly what makes it read as a UI box. */
.frame{
  position:absolute;inset:0;width:100%;height:100%;
  display:block;color:var(--ink);pointer-events:none;overflow:visible;
}
.t1{transform:rotate(-.7deg)}
.t2{transform:rotate(.5deg)}
.t3{transform:rotate(-.4deg)}

.t1:hover{transform:rotate(-.7deg) translateY(-3px)}
.t3:hover{transform:rotate(-.4deg) translateY(-3px)}
.t1:active{transform:rotate(-.7deg) translateY(1px)}
.t3:active{transform:rotate(-.4deg) translateY(1px)}
.tile:focus-visible{outline:2px solid var(--crayon);outline-offset:4px}

.tile .glyph,.tname,.tsub{position:relative;z-index:1}
.tile .glyph{display:block;color:var(--ink)}
.tile .glyph svg{width:26px;height:26px;display:block}
.tname{font-size:14px;line-height:1.2;text-align:center}
.tsub{font-size:11.5px;line-height:1.35;color:var(--ink-soft);text-align:center;
  font-variant-numeric:tabular-nums}

/* The HarmonyOS tile is a statement, not a button: a HarmonyOS NEXT app lives
   only in the on-device AppGallery catalogue, which has no web page to link
   to. Dashed, so the difference is visible before it is clicked. */
.tile.info{cursor:default}
/* Selectable on purpose: this string is meant to be copied into AppGallery's
   search box. The two link tiles resist selection the way links do; this one
   must not. */
.tile.info .tsub,.tile.info .tsub b{
  user-select:text;-webkit-user-select:text;cursor:text;
}
/* Schoolbell has no CJK glyphs, so the app's Chinese name is the one string on
   the page that hands off to a system face. Given its own weight rather than
   left looking like a font that failed to load. */
.tsub b{
  display:block;
  font-family:"JasonZH","PingFang SC","Hiragino Sans GB",sans-serif;
  font-weight:400;color:var(--ink);font-size:12.5px;letter-spacing:.05em;
  margin-top:1px;
}
.tile.soon{opacity:.5;pointer-events:none}

@media (max-width:340px){
  .tiles{gap:7px}
  .tname{font-size:12.5px}
  .tsub{font-size:10.5px}
}

/* ---------- what it is ---------- */
/* The drawn divider replaces the hairline rule that used to sit here — a
   crayon line on a crayon page. Multiply drops the white sheet it was scanned
   on, the same trick the cover uses. */
.divider{
  display:block;width:100%;max-width:240px;height:auto;
  margin:44px auto 6px;opacity:.9;mix-blend-mode:multiply;
}
/* Same drawing at the same size top and bottom; only the space around the
   closing one is tighter, because it separates the words from the footer
   rather than the download rows from the words. */
.about + .divider{margin:30px auto 0}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .divider{mix-blend-mode:screen;filter:brightness(1.25)}
}
:root[data-theme="dark"] .divider{mix-blend-mode:screen;filter:brightness(1.25)}

/* Centred throughout. The page is a drawing with words on it rather than a
   document, and a flush-left column fights the hand-lettered cover sitting
   directly above it. */
.about{margin:22px 0 0;text-align:center}

/* One sentence per line, at the author's request. Each is its own block rather
   than a <br>, so the gap between them is spacing that can be tuned and the
   long one can still wrap on a narrow screen without merging into its
   neighbour. Set a step below body size: this is description around the
   drawing, not the page's voice. */
.line{
  font-size:16px; line-height:1.75; color:var(--ink-soft);
  margin:0 auto 4px; max-width:40ch; text-wrap:balance;
}
.line:last-child{margin-bottom:0}
/* Where the two original paragraphs met. */
.line.gap{margin-top:22px}


/* ---------- the door ---------- */
.doorway{margin:16px 0 0;text-align:center}
/* The gap above and below the door is baked into the artwork, not the layout:
   the drawing sits in the middle of a 1200x900 canvas and only fills about
   44% of its height, so roughly a quarter of the canvas is blank at each end.
   The container is cut to the inked band and the full-size stage is offset
   upward inside it, which trims the space without scaling the door. */
.door{
  position:relative;width:100%;max-width:230px;margin:0 auto;
  aspect-ratio:1200/560;overflow:hidden;
}
.door-stage{position:absolute;left:0;right:0;top:-33.6%;aspect-ratio:1200/900}
.door-layer{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:contain;display:block;
  /* Line art on an opaque sheet, like every other drawing here. */
  mix-blend-mode:multiply;
}
/* The app throws this silhouette on the floor as a cast shadow. Here it stays
   where it is drawn, right on the door: the art multiplies over it, so the
   arch reads as shaded rather than as an outline with a shadow beside it.
   Deliberate — the flat-on-the-door version is the one that was preferred. */
.door-shadow{opacity:.5}
.door-hit{
  position:absolute;inset:0;width:100%;height:100%;
  background:none;border:0;padding:0;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
.door-hit:focus-visible{outline:2px solid var(--crayon);outline-offset:6px;border-radius:8px}

/* A knock moves the door, not the page: a short nudge, no easing on the way
   back, so it reads as a rap rather than a wobble. */
@keyframes door-knock{
  0%{transform:translate(0,0)}
  40%{transform:translate(1.5px,-1px)}
  100%{transform:translate(0,0)}
}
.door.is-knocking .door-art{animation:door-knock .16s ease}


@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .door-layer{
    filter:invert(1) hue-rotate(180deg) saturate(1.1);mix-blend-mode:screen;
  }
}
:root[data-theme="dark"] .door-layer{
  filter:invert(1) hue-rotate(180deg) saturate(1.1);mix-blend-mode:screen;
}
@media (prefers-reduced-motion:reduce){
  .door.is-knocking .door-art{animation:none}
}

/* ---------- footer ---------- */
footer{
  margin:8px 0 0;padding-top:2px;
  font-size:15px;line-height:2;color:var(--ink-soft);text-align:center;
}
footer a{color:var(--ink-soft);text-decoration:none;border-bottom:1px solid var(--rule)}
footer a:hover{color:var(--crayon);border-bottom-color:var(--crayon)}
footer .icp{margin-top:6px;opacity:.75;font-size:13.5px}

@media (prefers-reduced-motion:reduce){*{transition:none!important}}
@media (max-width:420px){
  body{font-size:17px;padding:0 18px 32px}
  .tile{padding:8px 4px;gap:5px}
  .fact dt{width:84px}
}

/* ---------- privacy page ---------- */
.doc{padding:20px 0 0}
.doc .back{font-size:16px;color:var(--ink-soft);text-decoration:none}
.doc .back:hover{color:var(--crayon)}
.doc h1{font-size:30px;font-weight:400;line-height:1.3;margin:22px 0 5px}
.doc .stamp{font-size:14.5px;color:var(--ink-soft);margin-bottom:30px}
.doc h2{font-size:21px;font-weight:400;margin:30px 0 8px}
.doc p{margin-bottom:14px;color:var(--ink-soft);max-width:48ch}
.doc p strong{color:var(--ink);font-weight:400;border-bottom:1.5px solid var(--crayon)}
.doc .lead{
  padding:16px 18px;border-radius:11px;background:var(--paper-edge);
  border-left:2px solid var(--crayon);color:var(--ink);margin-bottom:10px;max-width:none;
}
.doc a{color:var(--ink-soft);border-bottom:1px solid var(--rule);text-decoration:none}
.doc a:hover{color:var(--crayon);border-bottom-color:var(--crayon)}
