/* ═══════════════════════════════════════════════════════════════
   Apricot Grove 杏林行 · desktop.css
   Adaptive layer ONLY. Everything below 900px is untouched —
   the phone layout each page already ships stays exactly as-is.
   Load AFTER the page's own <style>:
       <link rel="stylesheet" href="desktop.css">
   ═══════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────────
   1 · TABLET  (720–899px)
   Still one column, just a roomier one. Portrait iPad, split-view.
   ───────────────────────────────────────────────────────────── */
@media (min-width: 720px) and (max-width: 899.98px) {
  /* width, not just max-width: index.html pins `width:min(100%,440px)` inline,
     and a max-width alone loses to it — which is why the town stayed a phone
     strip on a laptop while every other page widened. */
  #app { width: 100%; max-width: 620px; }
  .opt, .card, .bubble, .panel, .mapbox, .bio, .answer { font-size: 1.02em; }
}

/* ─────────────────────────────────────────────────────────────
   2 · DESKTOP  (≥ 900px)
   The phone column becomes a framed "cabinet" on the desk.
   ───────────────────────────────────────────────────────────── */
@media (min-width: 900px) {

  /* ── the frame ── */
  body {
    align-items: center;
    padding: 26px 0;
    overflow: hidden;
  }
  #app {
    width: 100%;
    max-width: 1120px;
    height: min(calc(100svh - 52px), 720px);   /* landscape cabinet, not a tall tower */
    border-radius: 22px;
    border: 1px solid rgba(58, 55, 48, .16);
    box-shadow: 0 26px 78px rgba(58, 55, 48, .34), 0 2px 0 rgba(255, 255, 255, .5) inset;
  }

  /* chrome sits inside the rounded frame, not against the window edge */
  .seal    { right: 20px; top: 18px; width: 34px; height: 34px; font-size: 19px; }
  .langBtn,
  .lang-toggle { left: 20px; top: 18px; padding: 6px 14px; font-size: 12px; }

  /* ── generous gutters ── */
  .screen { padding-left: 40px; padding-right: 40px; }

  /* ── reading measure: prose never runs the full 1120px ──
     English at 17px stays around 60–70 characters per line. */
  .q, .note, .hint, .bio, .ask, .fb, .teach, .answer, .end-wrap p {
    max-width: 660px;
    margin-left: auto;
    margin-right: auto;
  }

  /* ── answer choices become two columns ──
     6 options fit on one screen instead of scrolling. */
  .opts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    max-width: 880px;
    margin-left: auto;
    margin-right: auto;
    align-content: start;
  }
  .opt { min-height: 62px; }

  /* a lone call-to-action shouldn't stretch across the whole cabinet.
     display:block matters — buttons are inline-block by default, so once
     they stop filling the row they would sit side by side and collide. */
  .btn, .cta {
    display: block;
    max-width: 460px;
    margin-left: auto;
    margin-right: auto;
  }
  .btn + .btn, .cta + .cta { margin-top: 10px; }
  .btn-row .btn, .btn-row .cta { margin-top: 0; }
  .btn-row { max-width: 460px; margin-left: auto; margin-right: auto; }

  /* pointer devices get hover states; touch devices never did */
  .opt:hover:not(.used),
  .card:hover,
  .node:hover circle.pin { filter: brightness(1.03); }
  .opt:not(.used):hover { border-color: var(--sage-deep, #6E8B57); transform: translateY(-1px); }
  .card:hover { transform: translateY(-2px); }
  .opt, .card { transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease; }

  /* ═══ HUB (index.html) ═══
     Map on the left as the hero; identity, compass and the note on the right.

     These target `.hud-scroll`, not `#s4` directly: hud.js wraps every screen's
     children into `.hud-scroll` + `.hud-foot`, so the panels are grandchildren
     of #s4 and a grid declared on #s4 never reached them. That is why the
     desktop town shipped for weeks as a stack in a narrow column. */
  [data-page="hub"] #s4 .hud-scroll {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    column-gap: 26px;
    align-content: start;
  }
  [data-page="hub"] .hud-scroll .mapbox {
    grid-column: 1;
    grid-row: 1 / span 3;
    align-self: start;
    margin-bottom: 0;
  }
  /* the corner seal sits over the right rail here, so keep the streak clear of it */
  [data-page="hub"] .hud-scroll .topbar { grid-column: 2; grid-row: 1; padding-right: 46px; }
  [data-page="hub"] .hud-scroll .panel  { grid-column: 2; grid-row: 2; }
  [data-page="hub"] .hud-scroll .note   { grid-column: 2; grid-row: 3; max-width: none; align-self: start; }
  /* the footbar is a right rail on a landscape card — centre its buttons in it
     instead of leaving them stranded at the top of a tall empty column */
  [data-page="hub"] #s4 .hud-foot { justify-content: center; }

  [data-page="hub"] .topbar canvas { width: 48px; height: 54px; }
  [data-page="hub"] .topbar .stat  { min-width: 58px; }
  [data-page="hub"] .radar-wrap svg { width: 190px; height: 190px; }
  [data-page="hub"] .radar-wrap { gap: 18px; }

  /* character select: 2 × 2 instead of a tall stack */
  [data-page="hub"] .cards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    max-width: 880px;
    margin-left: auto;
    margin-right: auto;
  }
  [data-page="hub"] .card canvas { width: 66px; height: 74px; }

  /* the mentor sheet is a centred dialog, not a phone bottom-sheet */
  [data-page="hub"] .sheet {
    left: 50%;
    right: auto;
    bottom: 50%;
    transform: translate(-50%, 50%) scale(.97);
    width: min(560px, 90%);
    border-radius: 20px;
    opacity: 0;
    /* On the phone a closed sheet is pushed off the bottom of the screen, so it
       covers nothing. Centring it for desktop parks it over the middle of the
       card, where opacity:0 hides it from the eye but NOT from the mouse — an
       invisible 560px panel swallowing every click on the town beneath it.
       It has to stay in the layout to animate, so the pointer is what we turn
       off. Same rule the scrim has always had. */
    pointer-events: none;
  }
  [data-page="hub"] .sheet.on {
    transform: translate(-50%, 50%) scale(1);
    opacity: 1;
    pointer-events: auto;
  }

  /* ═══ CHAPTER ENGINE (chapter.html) ═══
     The dialogue screen splits: cast left, speech right.
     This is what kills the empty band in the middle. */
  /* The story stage is now illustration-over-dialogue on every screen size —
     one structure, so a fix on the phone cannot break the desktop and back.
     Desktop simply gives the picture more of the frame and centres the words. */
  [data-page="chapter"] #s-story .storyart { flex: 1 1 auto; }
  [data-page="chapter"] #s-story .storycard {
    padding-left: 40px;
    padding-right: 40px;
    align-items: center;
  }
  [data-page="chapter"] #s-story .bubble {
    width: 100%;
    max-width: 640px;
    min-height: 150px;
  }
  [data-page="chapter"] .actor canvas { width: 128px; height: 144px; }
  [data-page="chapter"] .actor span   { font-size: 12.5px; }

  /* the pulse / point-location stages get the height back */
  .arm-stage svg { max-height: 62svh; }
  #pulseWrap, .pulse-figure { max-width: 720px; margin-left: auto; margin-right: auto; }

  /* ending: the two reward cards sit side by side, everything else full width */
  [data-page="chapter"] #s-end .end-wrap {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 16px;
    justify-items: center;
    align-content: center;
    width: 100%;
    max-width: 900px;
    margin-left: auto;
    margin-right: auto;
  }
  [data-page="chapter"] #s-end .end-wrap > *          { grid-column: 1 / -1; width: 100%; max-width: 680px; }
  [data-page="chapter"] #s-end .end-wrap > .reward    { grid-column: auto; max-width: none; align-self: stretch; }
  [data-page="chapter"] #s-end .end-wrap > .cta       { max-width: 420px; }

  /* ═══ THE TWO HALLS (pointroom.html, herbroom.html) ═══
     The wall ships as two columns because that is right on a phone. On a
     1400px screen two columns of 42 points is twenty-one rows of scrolling
     for something that is meant to be scanned at a glance, so the shelf
     widens instead of the jars. The section headings span the full width,
     which is what keeps the shelves readable as shelves. */
  [data-page="pointroom"] .shelf,
  [data-page="herbroom"]  .shelf {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
  }
  .shelf .shelfhead { grid-column: 1 / -1; }
  .shelf .jar { min-height: 92px; }

  /* ═══ THE RECORD (progress.html) ═══
     Twenty chapters in one column is a long scroll on a landscape card. */
  [data-page="progress"] .rows {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 22px;
    row-gap: 6px;
  }
  /* a five-axis bar stretched across 1120px reads as a progress bar for the
     page, not for the axis — hold the meters to a sensible measure */
  [data-page="progress"] .axes,
  [data-page="progress"] .meter { max-width: 760px; }
  [data-page="progress"] .sec h2 { max-width: 760px; }

  /* ═══ REVIEW (review.html) ═══ */
  [data-page="review"] .rvlist {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    max-width: 880px;
    margin-left: auto;
    margin-right: auto;
  }
  [data-page="review"] .rvlist .rvsrc { grid-column: 1 / -1; }

  /* ═══ DAILY CASE ═══ */
  .sharegrid, .share { max-width: 660px; margin-left: auto; margin-right: auto; }

  /* ═══ DAOYIN / YIN-YANG mini-games ═══ */
  .grid5 {
    max-width: 620px;
    margin-left: auto;
    margin-right: auto;
    grid-template-columns: repeat(3, 1fr);
  }
  .gain, .taiji-wrap { max-width: 620px; margin-left: auto; margin-right: auto; }
}

/* ─────────────────────────────────────────────────────────────
   3 · WIDE DESKTOP (≥ 1400px) — a touch more air, nothing more.
   ───────────────────────────────────────────────────────────── */
@media (min-width: 1400px) {
  #app { width: 100%; max-width: 1240px; height: min(calc(100svh - 52px), 760px); }
  /* same specificity as the 900px rule above, or that one wins */
  [data-page="pointroom"] .shelf,
  [data-page="herbroom"]  .shelf { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* ─────────────────────────────────────────────────────────────
   4 · SHORT LANDSCAPE (phone held sideways, ≤ 520px tall)
   Shrink the big decorative elements so the button stays reachable.
   ───────────────────────────────────────────────────────────── */
@media (max-height: 520px) and (orientation: landscape) {
  .actor canvas { width: 54px; height: 61px; }
  .hero canvas  { width: 72px; height: 81px; }
  .title        { font-size: 30px; }
  .cast         { min-height: 70px; }
  .bubble       { min-height: 76px; }
}

/* ─────────────────────────────────────────────────────────────
   5 · MODALS ON DESKTOP
   A bottom sheet is a phone idiom. Across a 1240px landscape card it
   reads as a stray band at the foot of the page rather than a dialog —
   so the Retreat becomes a centred panel, matching the HUD trays.
   ───────────────────────────────────────────────────────────── */
@media (min-width: 900px) {
  .retreat {
    left: 50%;
    right: auto;
    bottom: 50%;
    width: min(560px, 84%);
    max-height: 84%;
    border-radius: 20px;
    transform: translate(-50%, 50%) scale(.96);
    opacity: 0;
    box-shadow: 0 26px 70px rgba(58, 55, 48, .38);
    /* Exactly the bug described above the hub sheet, and this one cost more:
       a closed Retreat sat invisibly over the centre of the card and ate every
       click on the answer buttons, so the whole story mode was unplayable on a
       laptop while looking completely normal. */
    pointer-events: none;
  }
  .retreat.on {
    transform: translate(-50%, 50%) scale(1);
    opacity: 1;
    pointer-events: auto;
  }
  /* the buttons inside a centred dialog should not stretch to full width */
  .rt-inner { padding: 24px 26px 26px; }
  .rt-x     { top: 8px; right: 8px; }
}
